c++ - 为什么 C++ 左值对象不能绑定(bind)到右值引用 (&&)?

标签 c++ c++11 move-semantics rvalue-reference

move 语义的想法是您可以从另一个临时对象(由右值引用引用)中获取所有内容并将该“所有内容”存储在您的对象中。这有助于避免在事物的单一构造就足够的情况下进行深度复制——因此您在右值对象中构造事物,然后将其 move 到长期存在的对象中。

为什么 C++ 不允许将左值对象绑定(bind)到右值引用?两者都允许我更改引用的对象,因此在访问引用对象的内部方面对我来说没有区别。

我能猜到的唯一原因是函数重载歧义问题。

最佳答案

But why C++ doesn't allow binding lvalue objects to rvalue references?

假设您的意思是“为什么 C++ 不允许将右值引用绑定(bind)到左值对象”:它允许。它只是不是自动的,因此您必须使用 std::move 使其显式化。

为什么?因为否则一个无害的函数调用可能会出人意料地破坏一些你没有预料到的东西:

Class object(much,state,many,members,wow);
looks_safe_to_me(object);
// oh no, it destructively copied my object!

对比

Class object(much,state,many,members,wow);
obviously_destructive(std::move(object));
// same result, but now the destruction is explicit and expected

关于破坏性复制的注意事项:为什么我在上面说破坏性破坏,我并不是说对象析构函数结束了它的生命周期:只是它的内部状态已经 move 到一个新的实例。它仍然是一个有效的对象,但不再像以前那样拥有昂贵的状态。


关于术语的注释:让我们看看是否可以消除上面对左值右值等的不精确使用。

引自cppreference为了后代:

  • lvalue

    an expression that has identity and cannot be moved from.

    所以,没有左值对象这样的东西,但是有一个对象在本地由左值表达式命名(或引用)

  • rvalue

    an expression that is either a prvalue or an xvalue. It can be moved from. It may or may not have identity.

    • prvalue(纯右值)大致是一个引用未命名临时对象的表达式:我们无法将左值表达式转换为这些 IIUC 之一。

    • xvalue(到期值)是

      an expression that has identity and can be moved from.

      明确包含 std::move

    • 的结果

那么实际发生了什么:

  • 一个对象存在
  • 对象由左值表达式在本地标识,不能从中 move (以保护我们免受意外副作用)
  • std::move 产生一个 xvalue 表达式(可以从中 move )引用与左值表达式相同的对象
  • 这意味着诸如变量(由左值表达式命名)之类的对象不能隐式 move ,而必须通过显式 xvalue 表达式显式 move ,例如std::move.
  • 匿名临时变量可能已经被 prvalue 表达式引用,并且可以隐式 move

关于c++ - 为什么 C++ 左值对象不能绑定(bind)到右值引用 (&&)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35652953/

相关文章:

c++ - 虚拟机制在虚拟析构函数的情况下如何工作

c++ - 在共享模式下锁定的 std::shared_mutex 上调用解锁

c++ - 使用 C++11 随机库在多线程中生成随机数是否像在多线程中使用 rand() 一样慢?

c++ - 在同一类中使用 constexpr 作为模板参数时出错

rust - 为什么调用 FnOnce 闭包是一个举动?

c++ - 成员函数返回成员变量的右值引用

pointers - 当 Vec 被 move 时,我可以(不安全地)持有一个指向 Vec 元素的指针吗?

c++ - 将 boost::shared_array<char> 转换为 boost::shared_array<const char>

c++ - vector 下标超出了迭代器的范围

c++ - 在现代 C++ 中使用非智能指针