gpt4 book ai didi

C++: std::move with rvalue reference 不 move 内容

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:21:41 24 4
gpt4 key购买 nike

示例程序:

#include <iostream>
#include <string>
#include <vector>

template <typename T>
void print(const T& _vec)
{
for( auto c: _vec )
std::cout << c << ",";
}

typedef std::vector<std::string> vecstr_t;

struct Trade
{
explicit Trade(vecstr_t&& vec) : _vec(vec )
{
}

vecstr_t _vec;
};


int main()
{
vecstr_t tmpV = {"ONE", "TWO", "THREE", "FOUR"};
std::cout << "size 1:" << tmpV.size() << "\t"; print(tmpV); std::cout << "\n" ;
Trade t(std::move(tmpV));
std::cout << "size 2:" << tmpV.size() << "\t"; print(tmpV); std::cout << "\n" ; // expted tmpV should be e,pty but it has original contents
print(t._vec);
}

我希望大小 2:应该为零,但输出为:

size 1:4    ONE,TWO,THREE,FOUR,
size 2:4 ONE,TWO,THREE,FOUR,
ONE,TWO,THREE,FOUR,

最佳答案

explicit Trade(vecstr_t&& vec) : _vec(vec)
{}

在上面的构造函数中,即使 vecvecstr_t 的右值引用类型,它本身也是一个左值。要记住的基本规则是 - if it has a name, it's an lvalue .

很少有左值可以自动 move 的上下文(例如按值返回对象的函数的 return 语句),但构造函数的 mem-initializer 列表不是一个他们中的。

在您的示例中,_vec 是从vec 复制构造的。如果您希望它改为 move 构造,请使用 std::move

explicit Trade(vecstr_t&& vec) : _vec(std::move(vec))
{}

现在第二次调用 print 将不会打印任何内容。请注意,从技术上讲,第二次调用可以打印非零大小,因为未指定从 vector move 的内容。但在大多数(可能是所有)实现中,您会看到一个空的 vector

Live demo


你在下面的评论说你的意图是接受右值和左值,只在前者的情况下 move ,否则复制参数。正如目前所写,您的构造函数将只接受右值,而不接受左值。有几种不同的选择可以实现您想要的效果。

最简单的可能是更改参数,使其按值获取参数,然后无条件 move 。

explicit Trade(vecstr_t vec) : _vec(std::move(vec))
{}

这种方法的缺点是您可能会导致 vector 的额外 move 构造,但是 move 构造 vector 的成本很低,您应该选择此选项在大多数情况下。

第二个选项是创建构造函数的两个重载

explicit Trade(vecstr_t&&      vec) : _vec(std::move(vec)) {}
explicit Trade(vecstr_t const& vec) : _vec(vec) {}

这个的缺点是重载的数量将随着构造函数参数数量的增加而呈指数增加。

第三种选择是使用完美转发。

template<typename V>
explicit Trade(V&& vec) : _vec(std::forward<V>(vec)) {}

上面的代码在转发构造函数时将保留传递给构造函数的参数的值类别以构造_vec。这意味着如果 vec 是右值,则将调用 vecstr_t move 构造函数。如果它是左值,它将被复制。

此解决方案的缺点是您的构造函数将接受任何类型的参数,而不仅仅是 vecstr_t,然后如果参数是,则内存初始化器列表中的 move/复制构造将失败不可转换为 vecstr_t。这可能会导致使用户感到困惑的错误消息。

关于C++: std::move with rvalue reference 不 move 内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31213539/

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