Boost logo

Boost Users :

Subject: [Boost-users] noncopyable and move semantics
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2011-07-25 19:04:15


Hello,
 
The current implementation of boost::noncopyable prevents derived classes
from declaring a defaulted move constructor:
 
#include <boost/noncopyable.hpp>
 
struct S : boost::noncopyable
{
    S(S&&) = default;
};
 
S f();
 
int main()
{
    S s = f();
}
 
Errors (with gcc trunk):
 
test3.cpp: In function 'int main()':
test3.cpp:12:13: error: use of deleted function 'S::S(S&&)'
test3.cpp:5:5: error: 'S::S(S&&)' is implicitly deleted because the default definition would be ill-formed:
/usr/include/boost/noncopyable.hpp:27:7: error: 'boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable&)' is private
test3.cpp:5:5: error: within this context
 
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.
 
If we give the definition of the S move constructor explicitly, all is
well because no one is trying to move or copy the noncopyable subobject:
 
struct S : boost::noncopyable
{
    S(S&&) {}
};
 
However, having to define the move constructor explicitly is annoying and
a maintenance hazard (e.g. if you add a data member, you have to add it
to the move constructor too).
 
If we modify noncopyable to give it a move constructor, the defaulted
move constructor now works in derived classes.
 
I think we should either give noncopyable a move constructor, or add a
similar class ("noncopyable_but_movable"? - I'm bad with names) that is
like noncopyable but also has a move constructor.
 
Thoughts?
 
Regards,
Nate.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net