You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C++中可两次从右值赋值?实测与《C++ Primer》描述存疑

关于C++中std::move后被移动对象值的困惑

我在阅读《C++ Primer》第13章时看到以下内容:

必须认识到,move调用承诺我们除了赋值或销毁外,不会再使用[右值]。move调用后,我们无法对被移动对象的值做任何假设。
我们可以销毁被移动对象,也可以为其赋新值,但不能使用被移动对象的值。

为了验证“无法重复使用被移动对象的值”,我编写了如下测试代码:

#include <iostream>

int main(int argc, const char * argv[]) {

    int&& rvalue = 42;
    
    int lvalue1 = std::move(rvalue);
    
    std::cout << "lvalue1 = " << lvalue1 << std::endl;
    
    int lvalue2 = std::move(rvalue);
    
    std::cout << "lvalue2 = " << lvalue2 << std::endl;
    
    return 0;
}

但基于C++11标准编译运行后,输出显示可多次使用被移动对象的值,这与书中描述矛盾,我对此感到困惑:

lvalue1 = 42
lvalue2 = 42

问题解析

  • 内置类型(如int)的移动操作本质就是拷贝。这类简单类型没有需要转移的复杂资源,std::move仅将右值引用转换为亡值(xvalue),但实际赋值时仍会拷贝值,所以多次读取原对象不会出问题。但这是编译器的实现行为,不是C++标准强制保证的。
  • 《C++ Primer》的描述针对的是拥有复杂资源的类类型(如std::string、std::vector)。这类对象被移动后,原对象会处于“有效但未定义”的状态——比如vector被移动后可能变为空,string被移动后可能变为空串,但标准没有规定具体状态,因此绝对不能依赖原对象的值,否则会导致未定义行为。

内容的提问来源于stack exchange,提问作者Autechre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 22:27:25