为何对返回右值的函数get_string_val()赋值无编译错误?
为什么
get_string_val()的赋值操作不会触发编译错误? 好问题!这其实是C++里关于临时对象、右值和成员函数调用的一个常见坑点,我来给你拆解清楚:
首先看你的代码:
std::string get_string_val() { std::string x; return x; } int main() { get_string_val() = "xxx"; }
1. 为什么编译不会报错?
C++中,临时对象(也就是这里get_string_val()返回的右值)是可以调用非const成员函数的。std::string的赋值运算符operator=是一个非const成员函数,所以编译器认为这个操作是合法的——它不会阻止你对临时对象执行赋值,只是这个操作的结果几乎没有实际意义。
2. 代码实际执行了什么?
你猜的没错,赋值操作确实是作用在get_string_val()返回的临时std::string对象上:
- 调用
get_string_val()时,函数内部创建了局部变量x,然后返回它的副本(也就是一个临时对象); - 紧接着,这个临时对象调用
operator=,把字符串字面量"xxx"赋值给自己; - 当这条语句执行结束后,这个临时对象会被立即销毁,所有赋值的结果都随之消失——没有任何持久化的变量被修改。
3. 为什么这是个严重的bug?
如果你的实际场景是:原本想让函数返回类成员变量的引用(比如std::string& get_string_val()),这样赋值就能直接修改成员变量,但不小心写成了返回值(std::string),那么所有的赋值操作都会像上面这样,只作用在临时对象上,而真正要修改的成员变量完全没变化。这种bug非常隐蔽,因为编译不会报错,但程序逻辑会完全不符合预期。
如何提前发现这类问题?
如果你的函数返回值不应该被修改,可以把返回类型设为const std::string或者const std::string&,这样编译器就会对get_string_val() = "xxx"这种赋值操作直接报错,帮你提前发现问题。
内容的提问来源于stack exchange,提问作者lichi101
相关产品推荐
相关产品推荐

