考虑以下代码:
#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
is noncopyable
因此std::vector<A>
无法复制。因此我无法返回std::vector<A>
来自一个函数。
然而,考虑到 RVO 的概念,这种事情是不可能发生的,这对我来说是不对的。如果此处应用返回值优化,则可以省略复制构造并且调用getVec()
将是有效的。
那么执行此操作的正确方法是什么?这在 VS2010 / C++11 中可能吗?
If return vec;
无法编译,VS2010 还不完全支持移动语义。通常,如果从函数返回,自动变量会隐式移动。使用return std::move(vec);
作为临时解决方法,并在脑海中记下以摆脱std::move
将来。
可以找到完整的解释在这个常见问题解答中 https://stackoverflow.com/a/11540204/标题为“退出职能”。
此外,您的双参数构造函数会创建通过引用 const 传递的字符串参数的副本。我建议改为按值获取参数并将其移至成员中:
A(int num, std::string name) : num(num), name(std::move(name)) { }
这样,您就可以最大程度地减少所需副本的数量。看想要速度吗?按值传递 http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/了解详情。
另外,由于您的移动构造函数没有执行任何特殊操作,因此您可以default
it:
A(A&& other) = default;
这使得它在面对变化时更加稳健。 Bug 很少隐藏在您不编写的代码中:)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)