为什么这段C++代码中的std::string没有在编译时报错?

4

我有以下代码片段:

#include <string>

int main(int argc, char *argv[])
{
    std::string a, b, c;
    a + b = c;
    return 0;
}

为什么这段 C++ 代码不会在编译时出错?可能是因为std::string::operator+的实现方式,但我的问题是:为什么要以这种方式实现它?在什么情况下需要这样的行为?

1
为什么会出现编译错误?a+B返回一个有效的字符串对象。至于使用?它可能无法使用。 - David Haim
4
OP可能认为它会失败,原因与a、b、cint类型时相同。 - juanchopanza
有人能列举一个有效的使用案例吗? - Karoly Horvath
@KarolyHorvath 任何有效的用例都将涉及具有副作用的构造函数、析构函数或operator=;在任何其他情况下,该表达式的行为类似于无操作,我认为。 - Paolo M
@PaoloM:我的意思是针对 std::string - Karoly Horvath
1个回答

7

您可以将值赋给临时对象,没有任何规则阻止这样做。

如果您不希望成员函数在临时对象(或更一般的r-value)上被调用,您可以在函数声明中使用ref-qualifier

但正如您可以在这里看到的那样,std::string::operator=没有ref-qualified版本。

我认为标准委员会并没有以明确的目标允许这种行为;我猜测这个选择背后的理由是尽可能地对程序员施加最少的规则,并让他自己找到有用的应用,如果存在的话。


我猜问题在于,临时变量的“临时”有多长时间。对于class X a,b,c; a+b = c;这样的表达式,其结果可能是期望的,其中临时变量导致某些修改的全局状态被更新。 - mksteve
对我来说,具有副作用的赋值运算符听起来像一个巨大的反模式。 - DarkWanderer
@DarkWanderer 我不知道“抛出”是否可以被视为副作用,但是赋值运算符肯定可以抛出异常。 - Paolo M
可以这样做,但是如果这样使用,那么编写该代码的人将会依赖于该抛出异常,这也是一种代码异味。 - DarkWanderer
@DarkWanderer 当然会的。 - Paolo M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接