为何std::string的a + b右值表达式可被赋值?
关于
std::string右值赋值的疑问 代码示例
#include <iostream> #include <string> int main() { std::string a; std::string b; a + b = "dadas"; }
调试命令
PS D:\WeCode\local_c++> & 'c:\Users\z00841303.vscode\extensions\ms-vscode.cpptools-1.5.1\debugAdapters\bin\WindowsDebugLauncher.exe' '--stdin=Microsoft-MIEngine-In-1vidcjmy.adn' '--stdout=Microsoft-MIEngine-Out-ur4nmbvf.4bj' '--stderr=Microsoft-MIEngine-Error-kdush30f.pk5' '--pid=Microsoft-MIEngine-Pid-5hgspuj4.obh' '--dbgExe=D:\Program Files\mingw\MinGW\bin\gdb.exe' '--interpreter=mi'
核心疑问
定义std::string对象a和b后,执行a + b = "abc"这类操作为何可行?已知a+b是右值表达式,为何能对其进行赋值?
解答
这是因为C++里的右值并非绝对不能被赋值,关键看右值的类型是否重载了operator=,且该运算符允许接收右值作为左操作数。
std::string的operator+返回的是一个临时std::string对象(右值),而std::string的赋值运算符operator=有多个重载版本,核心签名包括:
basic_string& operator=(const char* s);
这些赋值运算符的左操作数是std::string&(非常量引用),而C++标准允许临时对象绑定到非const成员函数的this指针——简单说就是,临时std::string对象可以调用自己的非const成员函数,包括赋值运算符。
所以a + b = "dadas"的执行逻辑是:
- 先计算
a + b,生成一个临时的std::string右值对象; - 调用这个临时对象的
operator=,把字符串字面量"dadas"赋值给它; - 赋值完成后,临时对象立刻被销毁,原有的a和b的值不会有任何变化,这个操作本质上没有实际意义。
需要注意的是,这种写法虽然合法,但属于无意义的代码,大部分编译器开启警告(比如GCC的-Wall选项)时会提示“将临时值用作左值”。
内容的提问来源于stack exchange,提问作者jay_zj
相关产品推荐
相关产品推荐

