gpt4 book ai didi

c++ - 调用复制 ctor 而不是移动 ctor

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:18:39 25 4
gpt4 key购买 nike

为什么从 bar 返回时调用复制构造函数而不是移动构造函数?

#include <iostream>

using namespace std;

class Alpha {
public:
Alpha() { cout << "ctor" << endl; }
Alpha(Alpha &) { cout << "copy ctor" << endl; }
Alpha(Alpha &&) { cout << "move ctor" << endl; }
Alpha &operator=(Alpha &) { cout << "copy asgn op" << endl; }
Alpha &operator=(Alpha &&) { cout << "move asgn op" << endl; }
};

Alpha foo(Alpha a) {
return a; // Move ctor is called (expected).
}

Alpha bar(Alpha &&a) {
return a; // Copy ctor is called (unexpected).
}

int main() {
Alpha a, b;
a = foo(a);
a = foo(Alpha());
a = bar(Alpha());
b = a;
return 0;
}

如果 bar 执行 return move(a) 则行为符合预期。我不明白为什么调用 std::move 是必要的,因为 foo 在返回时调用移动构造函数。

最佳答案

在这种情况下有两件事需要理解:

  1. a in bar(Alpha &&a) 是一个命名的右值引用;因此,被视为左值。
  2. a 仍然是引用。

第 1 部分

由于 bar(Alpha &&a) 中的 a 是一个命名的右值引用,因此它被视为左值。将命名右值引用视为左值的动机是为了提供安全性。考虑以下问题,

Alpha bar(Alpha &&a) {
baz(a);
qux(a);
return a;
}

如果 baz(a)a 视为右值,则可以自由调用移动构造函数,而 qux(a) 可能是无效的。该标准通过将命名右值引用视为左值来避免此问题。

第 2 部分

由于a仍然是一个引用(并且可能引用bar范围之外的对象),bar调用复制构造函数回来的时候。这种行为背后的动机是提供安全。

引用资料

  1. SO Q&A - return by rvalue reference
  2. Kerrek SB 的评论

关于c++ - 调用复制 ctor 而不是移动 ctor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45807900/

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