gpt4 book ai didi

c++ - 为什么我必须在右值引用上调用 move?

转载 作者:可可西里 更新时间:2023-11-01 17:44:33 25 4
gpt4 key购买 nike

在下面的代码中,为什么第一个调用 mkme = mvme_rv 不分派(dispatch)给 T& operator=(const T&&)

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

using namespace std;
using T = vector<int>;

int main()
{
T mvme(10, 1), mkme;
T&& mvme_rv = move(mvme); // rvalue ref?
mkme = mvme_rv; // calls T& operator=(const T&)?
cout << mvme.empty(); // 0
mkme = move(mvme_rv); // calls T& operator=(const T&&)?
cout << mvme.empty(); // 1
}

最佳答案

正如 skypjack 正确评论的那样,通过名称访问对象总是会产生左值引用。

这是一项安全功能,如果您仔细考虑,您会发现自己很高兴。

如您所知,std::move 只是将左值引用转换为右值引用。如果我们立即使用返回的右值引用(即未命名),那么它仍然是右值引用。

这意味着只能在代码中提到 move(x) 的地方使用 r 值。从代码阅读者的角度来看,现在很容易看出 x 的状态在哪里变得未定义。

所以:

 1: auto x = make_x();
2: auto&& r = std::move(x);
3: // lots of other stuff
35: // ...
54: // ...
55: take_my_x(r);

不起作用。如果是这样,维护代码的人将很难看到(并记住)x(在第 1 行定义)通过第 2 行的引用在第 55 行进入未定义状态。

这更明确:

 1: auto x = make_x();
2: //
3: // lots of other stuff
35: // ...
54: // ...
55: take_my_x(std::move(x));

关于c++ - 为什么我必须在右值引用上调用 move?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39386441/

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