【问题标题】:c++17 structured bindings and move semantics [duplicate]c ++ 17结构化绑定和移动语义[重复]
【发布时间】:2020-12-27 06:01:15
【问题描述】:

我正在阅读此 https://leanpub.com/cppmove (C++17 - The Complete Guide First Edition Nicolai M. Josuttisand) 并关于 c++17 结构化绑定和移动语义,它给出了以下示例,其中从对象 ms 移动保持原样:

MyStruct ms = { 42, "Jim" };   // struct has fields {int i, std::string s}
auto&& [v,n] = std::move(ms); 

// author says: the structured bindings v and n refer to an anonymous
// entity being an rvalue reference to ms, while ms still holds its value:

std::cout << "ms.s: " << ms.s << '\n'; // prints "Jim"

我已经对此进行了测试,至少在实际运行中,这是正确的。但这通常也是它应该如何工作的吗?按照作者之前对结构化绑定的解释的方式,上面应该等同于

MyStruct ms = { 42, "Jim" };
auto&& e = std::move(ms); // anonymous compiler constructed entity "e"
/*aliasname*/ v = e.i; // v and n act as if e was constructed as
                       // above and v/n assigned to e.i/e.s as here
/*aliasname*/ n = e.s;

std::cout << "ms.s: " << ms.s << '\n'; // prints "Jim"

问题:

所以如果这是一个有效的解释,auto&amp;&amp; e = std::move(ms) 会不会导致ms 立即将其内容“移动”/“被盗”/“无效”?这样在“Jim”上面的两个(等效?)变体中都不会(保证)打印...?

澄清:我知道 std::move 不会移动任何东西,而是从左值转换为右值,但我认为这意味着至少你不能指望 std::move -ed 对象(此处为 ms)内容在后续使用中被保留/可用

标记为 What is std::move(), and when should it be used? 的骗子。然而,对于这个问题,有大约 300 人赞成,这个答案是:https://stackoverflow.com/a/27026280/11608725

首先要注意的是 std::move() 实际上并没有移动 任何事物。它将表达式从左值(例如 命名变量)成为一个xvalue。一个 xvalue 告诉编译器:

你可以掠夺我,移动我持有的任何东西并在其他地方使用 (反正我很快就会被毁掉)”。

换句话说,当您使用 std::move(x) 时,您允许 编译器蚕食 x

所以我想混乱是允许的:-P

请为超傻瓜推荐一本关于 c++17 和移动​​语义的好书——这本书的请求肯定是正确的;-)

【问题讨论】:

  • 我认为您对std::move 有误解。实际上std::move 既不移动也不构造任何东西。 auto&amp;&amp; e = std::move(ms); 中没有构造函数调用。
  • @churill,是的,但move 不应该等同于声明不能再指望ms 保留其原始内容,不是吗?
  • std::move 函数实际上并没有移动任何东西。 move 构造函数 可以,std::move 允许您调用 move 构造函数。但在这种情况下,你没有这样做; auto&amp;&amp; 提供参考。我很确定在这两个示例中,对 std::move 的调用没有任何用处。
  • std::move 只是一个演员表。它将你给它的任何东西转换为一个 xvalue,这样你就可以从它移动,如果你把它给它会实际移动它的东西,比如移动构造函数。
  • @NathanOliver,是的,但这是否意味着后续使用 ms 的合同?它的内容可能已被移动,所以不要指望它存在?

标签: c++ c++17 move-semantics structured-bindings


【解决方案1】:

auto&amp;&amp; e = std::move(ms) 不会导致 ms 立即将其内容“移动”/“被盗”/“无效”吗?

std::move() 只准备ms 被移动,它不会直接从它移动。这就是为什么eMyStruct引用,而不是实际的MyStruct 对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多