[move] Movable but not copyable bug?

Given the following code, if (1) is uncommented then it fails to compile under C++03 mode yet works in C++11 mode. If commented out, then it compiles successfully under both modes. (g++ 4.8.2 is being used) Is this behavior expected or a bug? #include <boost/move/core.hpp> #include <boost/move/utility.hpp> struct Foo { Foo(int x, int y) {} Foo(BOOST_RV_REF(Foo) rhs) {} private: //Purposefully declared and not defined. Foo & operator=(Foo); private: BOOST_MOVABLE_BUT_NOT_COPYABLE(Foo) }; template <typename T> struct Bar { Bar() : f(0, 1) {} // (1) // Bar(Bar const & rhs) // : f(rhs.f) // {} Bar(BOOST_RV_REF(Bar) rhs) : f(::boost::move(rhs.f)) {} private: //Purposefully declared and not defined. Bar & operator=(Bar); private: BOOST_COPYABLE_AND_MOVABLE(Bar) private: T f; }; Foo f1() { // (2) // Foo f(0, 1); // return f; // (3) return Foo(0, 1); } Bar<Foo> f2() { return Bar<Foo>(); } int main() { // Foo f( f1() ); Bar<Foo> b(Bar<Foo>()); return 0; }

On Sat, 23 Aug 2014 17:55:06 -0700, Mostafa <mostafa_working_away@yahoo.com> wrote:
Given the following code, if (1) is uncommented then it fails to compile under C++03 mode yet works in C++11 mode. If commented out, then it compiles successfully under both modes. (g++ 4.8.2 is being used) Is this behavior expected or a bug?
FWIW, both scenarios compile in VS2005. It seems gcc is unnecessarily instantiating (in function f2) the copy ctor for Bar<Foo> whenever that ctor is explicitly defined. Is this a gcc bug?

El 24/08/2014 2:55, Mostafa escribió:
Given the following code, if (1) is uncommented then it fails to compile under C++03 mode yet works in C++11 mode. If commented out, then it compiles successfully under both modes. (g++ 4.8.2 is being used) Is this behavior expected or a bug?
private: //Purposefully declared and not defined. Foo & operator=(Foo);
BOOST_MOVABLE_BUT_NOT_COPYABLE(Foo) already makes copy assignment private. See Boost.Move documentation. Returning by value requires CopyConstructible in C++03 compilers. If you declare that operation in Bar, then the compiler will use it. If you leave it out, Boost.Move magic will make moveable-only objects returnable by value. I think that you need BOOST_MOVE_RET to obtain portable behaviour: http://www.boost.org/doc/libs/1_56_0/doc/html/BOOST_MOVE_RET.html Best, Ion
participants (2)
-
Ion Gaztañaga
-
Mostafa