gpt4 book ai didi

C++11/VS2010 : Returning containers of uncopyable but movable objects

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:06:32 25 4
gpt4 key购买 nike

考虑以下代码:

#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 下编译,因为很明显 Anoncopyable因此 std::vector<A>无法复制。因此我不能返回 std::vector<A>来自函数。

然而,考虑到 RVO 的概念,我觉得这种事情是不可能的。如果此处应用返回值优化,则可以省略复制构造并调用 getVec()将是有效的。

那么正确的做法是什么?这在 VS2010/C++11 中完全可行吗?

最佳答案

如果 return vec; 不编译,VS2010 还不完全支持 move 语义。通常,如果从函数返回,自动变量会被隐式 move 。使用 return std::move(vec); 作为临时解决方法,并在脑海中记下以在将来摆脱 std::move

可以找到完整的解释 in this FAQ answer在“移出功能”的标题下。

此外,您的双参数构造函数复制了通过引用到常量传递的字符串参数。我建议改为按值获取参数并将其 move 到成员中:

A(int num, std::string name) : num(num), name(std::move(name)) { }

这样,您可以最大限度地减少必要的拷贝数。参见 Want Speed? Pass by Value了解详情。

此外,由于您的 move 构造函数没有做任何特殊的事情,您可以默认它:

A(A&& other) = default;

这使得它在面对变化时更加健壮。错误很少隐藏在您不编写的代码中:)

关于C++11/VS2010 : Returning containers of uncopyable but movable objects,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11608490/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com