Consider the following code:
#include <vector>
#include <boost/noncopyable.hpp>
struct A : private boost::noncopyable
{
A(int num, const std::string& name)
: num(num),
name(name)
{
}
A(A&& other)
: num(other.num),
name(std::move(other.name))
{
}
int num;
std::string name;
};
std::vector<A> getVec()
{
std::vector<A> vec;
vec.emplace_back(A(3, "foo"));
// vec.emplace_back(3, "foo"); not available yet in VS10?
return vec; // error, copy ctor inaccessible
}
int main ( int argc, char* argv[] )
{
// should call std::vector::vector(std::vector&& other)
std::vector<A> vec = getVec();
return 0;
}
This does not compile under VS2010 because obviously A is noncopyable and thus std::vector<A> cannot be copied. Accordingly I cannot return a std::vector<A> from a function.
However it doesn’t feel right to me that this sort of thing is not possible considering the concept of RVO. If Return Value Optimization was applied here, copy construction could be omitted and the call to getVec() would be valid.
So what would be the proper way to do this? Is this possible at all in VS2010 / C++11?
If
return vec;does not compile, VS2010 does not support move semantics fully yet. Normally, automatic variables are moved implicitly if returned from a function. Usereturn std::move(vec);as an interim workaround, and make a note in your head to get rid of thestd::movein the future.A full explanation can be found in this FAQ answer under the headline “Moving out of functions”.
Also, your two-argument constructor makes a copy of the string argument which is passed by reference-to-const. I would suggest taking the argument by value instead and moving it into the member:
This way, you minimize the number of necessary copies. See Want Speed? Pass by Value for details.
Also, since your move constructor doesn’t do anything special, you can
defaultit:This makes it more robust in the face of changes. Bugs seldomly hide in the code you don’t write 🙂