Opened 10 years ago

Closed 10 years ago

#7969 closed Bugs (fixed)

BOOST_MOVABLE_BUT_NOT_COPYABLE makes it impossible to use type in GCC containners in C++11

Reported by: Antony Polukhin Owned by: Ion Gaztañaga
Milestone: To Be Determined Component: move
Version: Boost Development Trunk Severity: Problem
Keywords: c++11 c++0x noncopyable stl Cc:

Description

BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE) defines:

TYPE(const TYPE &); TYPE& operator=(const TYPE &);

which makes GCC assume that class have copy constructor and assignment operator. That makes STL containers to choose assignment operator instead of move assignment.

The solution would be to mark them in c++11 with '= delete' or not write them at all (compiler shall not generate copy constructors if there is a move constructor, but this may not work on some compilers):

#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
#define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
      public:\
      typedef int boost_move_emulation_t;\
      private:\
      TYPE(const TYPE &) = delete;\
      TYPE& operator=(const TYPE &) = delete;\
#else
#define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
      public:\
      typedef int boost_move_emulation_t;\
      private:\
#endif

Example to reproduce the error:

#include <boost/move/move.hpp>
#include <vector>

class descriptor_owner_movable {
    void* descriptor_;

    BOOST_MOVABLE_BUT_NOT_COPYABLE(descriptor_owner_movable)
public:
    descriptor_owner_movable(){}

    descriptor_owner_movable(BOOST_RV_REF(descriptor_owner_movable) param) {}

    descriptor_owner_movable& operator=(BOOST_RV_REF(descriptor_owner_movable) param) {
        return *this;
    }
};


int main() {
    std::vector<descriptor_owner_movable> vec;
    vec.resize(10);
    return 0;
}

Tested on GCC 4.7.2 with -std=c++0x flag

Change History (6)

comment:1 by viboes, 10 years ago

Ion, in case this could help, Boost.Thread contains already a boost/thread/detail/delete.hpp file defining BOOST_THREAD_NO_COPYABLE that could help you.

comment:2 by Ion Gaztañaga, 10 years ago

Resolution: fixed
Status: newclosed

(In [82706]) Fixes #7969

comment:3 by Ion Gaztañaga, 10 years ago

Thanks for the report and hint. Let me know if the patch fixes the issue.

comment:4 by viboes, 10 years ago

Resolution: fixed
Status: closedreopened

Ion, IIRC your macros were expected to be included on the private part.

 Put the following macro in the private section: BOOST_MOVABLE_BUT_NOT_COPYABLE(classname) 

After the change (line 224) BOOST_MOVABLE_BUT_NOT_COPYABLE stay in the public part. This should be fixed.

comment:5 by Ion Gaztañaga, 10 years ago

Let's see if [82711] definitely fixes it.

comment:6 by Ion Gaztañaga, 10 years ago

Resolution: fixed
Status: reopenedclosed

Reported in the boost mailing list that GCC 4.7.2 works fine now.

Note: See TracTickets for help on using tickets.