【发布时间】:2012-07-21 10:48:27
【问题描述】:
考虑以下代码:
#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;
}
这在 VS2010 下无法编译,因为显然 A 是 noncopyable,因此无法复制 std::vector<A>。因此,我无法从函数返回 std::vector<A>。
但是,考虑到 RVO 的概念,我觉得这种事情是不可能的。如果此处应用了返回值优化,则可以省略复制构造,并且对 getVec() 的调用将是有效的。
那么正确的方法是什么?这在 VS2010 / C++11 中是否可能?
【问题讨论】:
-
RVO 并没有取消东西可复制的要求。
-
您的成员初始化列表中数据成员的顺序(先是
num,然后是name)与类底部数据成员的声明顺序不匹配(首先name,然后是num)。一般来说,这会导致非常令人惊讶的错误,所以我总是会努力使订单保持一致。 -
另外,
std::vector<A> vec = getVec();不是一个赋值,而是一个初始化(准确地说是复制初始化)。 -
尝试添加移动赋值运算符。这使它在 GCC 中为我编译。 (虽然我的错误在不同的地方)
-
@FredOverflow:您对这两件事是正确的,谢谢。现在已修复,因为它与实际问题没有任何关系。
标签: c++ visual-studio-2010 visual-c++ c++11 move-semantics