noncopyable and move semantics
Hello,
The current implementation of boost::noncopyable prevents derived classes
from declaring a defaulted move constructor:
#include
On 25 July 2011 18:04, Nathan Ridge
struct S : boost::noncopyable { S(S&&) = default; };
The problem is that the default move constructor for S tries to move the noncopyable base subobject, but noncopyable does not have a move constructor (one isn't generated implicitly because a user-defined copy constructor is present). Then it tries to fall back to the noncopyable copy constructor, but that of course is private.
Doesn't the problem go away if you don't use boost::noncopyable at all? If one agrees that the C++0x mechanism is superior, is there still a use case under C++0x for boost::noncopyable? -- Nevin ":-)" Liber mailto:nevin@eviloverlord.com (847) 691-1404
On 25 July 2011 18:04, Nathan Ridge
mailto:zeratul976@hotmail.com> wrote: struct S : boost::noncopyable { S(S&&) = default; };
The problem is that the default move constructor for S tries to move the noncopyable base subobject, but noncopyable does not have a move constructor (one isn't generated implicitly because a user-defined copy constructor is present). Then it tries to fall back to the noncopyable copy constructor, but that of course is private.
Doesn't the problem go away if you don't use boost::noncopyable at all? If one agrees that the C++0x mechanism is superior, is there still a use case under C++0x for boost::noncopyable?
Less typing and more self-documenting than doing it yourself? Isn't that what boost::noncopyable was for in C++03, too? Regards, Nate.
On 7/26/2011 11:35 AM, Nevin Liber wrote:
Doesn't the problem go away if you don't use boost::noncopyable at all? If one agrees that the C++0x mechanism is superior, is there still a use case under C++0x for boost::noncopyable?
Because some compilers support move references but don't support the =delete syntax. In my mind "no copy" does not say anything about the ability to move. In fact, move will typically be just dandy if the compiler handles it. So I would like that meaning. —John
On 28 July 2011 04:53, John M. Dlugosz
On 7/26/2011 11:35 AM, Nevin Liber wrote:
Doesn't the problem go away if you don't use boost::noncopyable at all?
If one agrees that the C++0x mechanism is superior, is there still a use case under C++0x for boost::noncopyable?
Because some compilers support move references but don't support the =delete syntax.
You don't need =delete (or any) syntax for this. If you declare a move constructor, the copy constructor is implicitly declared (by the compiler) as deleted. Admittedly, this doesn't address the case for older compilers that don't implement the rules that came out of the C++0x Batavia meeting. In my mind "no copy" does not say anything about the ability to move. In
fact, move will typically be just dandy if the compiler handles it. So I would like that meaning.
In order to reduce the chances of silently breaking existing code, the rules of C++0x were chosen so that a C++03 "noncopyable" (in quotes because in C++03 the closest we can get to that is to have an unimplemented private copy constructor and copy assignment operator) class automatically is a noncopyable+nonmoveable class under C++0x. I really don't think we should mess with that. -- Nevin ":-)" Liber mailto:nevin@eviloverlord.com (847) 691-1404
In order to reduce the chances of silently breaking existing code, the rules of C++0x were chosen so that a C++03 "noncopyable" (in quotes because in C++03 the closest we can get to that is to have an unimplemented private copy constructor and copy assignment operator) class automatically is a noncopyable+nonmoveable class under C++0x. I really don't think we should mess with that.
That's fine, but then could we introduce a different class that inhibits copying but not moving? I think this would be useful, as in a large percentage of cases, when you want an object to be non- copyable, you still want it to be movable. Regards, Nate
On 28 July 2011 13:58, Nathan Ridge
That's fine, but then could we introduce a different class that inhibits copying but not moving? I think this would be useful, as in a large percentage of cases, when you want an object to be non- copyable, you still want it to be movable.
I don't see anything wrong with that. I'm not sure how useful it is, as it only makes a real semantic difference when you want the implicitly declared move constructor and move assignment operator but no copying, which I'm guessing is rare (but I really don't have enough experience with r-value references to say more than that). -- Nevin ":-)" Liber mailto:nevin@eviloverlord.com (847) 691-1404
On 28 July 2011 13:58, Nathan Ridge
mailto:zeratul976@hotmail.com> wrote: That's fine, but then could we introduce a different class that inhibits copying but not moving? I think this would be useful, as in a large percentage of cases, when you want an object to be non- copyable, you still want it to be movable.
I don't see anything wrong with that. I'm not sure how useful it is, as it only makes a real semantic difference when you want the implicitly declared move constructor and move assignment operator but no copying, which I'm guessing is rare (but I really don't have enough experience with r-value references to say more than that).
On the other hand, I think that is the most common case: - you don't want to allow copying, either because it doesn't make sense semantically, or because it's too inefficient - you want to allow moving so that e.g. you can store the object in a container without having to add a layer of indirection such as unique_ptr - the default move constructor does the correct thing (just like in most cases, the default copy constructor does the correct thing) Regards, Nate.
On 28 July 2011 18:12, Nathan Ridge
On the other hand, I think that is the most common case:
- you don't want to allow copying, either because it doesn't make sense semantically, or because it's too inefficient - you want to allow moving so that e.g. you can store the object in a container without having to add a layer of indirection such as unique_ptr - the default move constructor does the correct thing (just like in most cases, the default copy constructor does the correct thing)
In most (if not all) of the above cases, the rules of C++0x will already do the right thing. If I want to allow moving but not copying, all I have to do is declare a move constructor. What exactly do I need the noise of an extra header and deriving from some boost::moveableonly class for? It's more for the readers of my code to learn with no semantic benefit, and given that they have to learn the C++0x rules anyway, I probably would never use such a class. boost::noncopyable bought us something in C++03. I really don't see what boost::noncopyable or some boost::moveableonly class buys us in C++0x. -- Nevin ":-)" Liber mailto:nevin@eviloverlord.com (847) 691-1404
In most (if not all) of the above cases, the rules of C++0x will already do the right thing. If I want to allow moving but not copying, all I have to do is declare a move constructor. What exactly do I need the noise of an extra header and deriving from some boost::moveableonly class for?
Oh! I didn't know declaring a move constructor inhibited the generation of a copy constructor. That's neat! And it indeed removes the need for the boost::moveableonly that I was suggesting. Guess you learn something new every day... Regards, Nate.
On 7/28/2011 6:12 PM, Nathan Ridge wrote:
On 28 July 2011 13:58, Nathan Ridge
mailto:zeratul976@hotmail.com> wrote: That's fine, but then could we introduce a different class that inhibits copying but not moving? I think this would be useful, as in a large percentage of cases, when you want an object to be non- copyable, you still want it to be movable.
On the other hand, I think that is the most common case:
I agree, I think that will be a common case. Having a different base class name prevents silent breaking code, and can be better targeted to address this case. It will be useful for giving uniform meaning on all compilers, which in real life interpret the specs differently or have partial support. Hide that portability issues inside the class.
participants (3)
-
John M. Dlugosz
-
Nathan Ridge
-
Nevin Liber