为何std::move传递给异常构造函数后原std::string变量未被修改?
问题解答
你遇到的现象和编译器优化完全无关,核心原因是**std::invalid_argument没有接受std::string&&右值参数的构造函数重载**。
C++标准中,std::invalid_argument的基类std::logic_error仅提供两个公开构造函数:
explicit logic_error( const std::string& what_arg );explicit logic_error( const char* what_arg );
你传入的std::move(msg)是std::string类型的右值,但右值可以合法绑定到const左值引用,因此编译器会匹配第一个构造函数,直接拷贝msg的内容生成异常对象,全程不会调用std::string的移动构造函数,自然不会修改原msg的内容。
补充两个容易混淆的移动语义知识点:
std::move本身不执行任何移动操作,它仅将对象转换为右值类型,真正的移动逻辑由对应类型的移动构造/移动赋值运算符实现,没有匹配到移动重载就不会发生移动行为。- 就算真的触发了
std::string的移动构造,原对象的状态也是标准未明确规定的合法状态,不一定会被置空:比如大部分实现的短字符串优化(SSO)场景下,长度小于SSO阈值的字符串移动时会直接拷贝内容,原字符串不会被清空,这是符合标准要求的。
如果想要避免字符串拷贝,可以直接传入msg.c_str()给异常构造函数,不需要通过std::string传递。
内容的提问来源于stack exchange,提问作者digito_evo
相关产品推荐
相关产品推荐

