为什么+ =标准库中的有效临时值?

时间:2012-03-08 01:08:57

标签: c++ temporary

当我尝试在ideone上编译以下内容时:

class X
{
  public:
   friend X& operator+=(X& x, const X& y);
};

X& operator+=(X& x, const X& y) { return x; }

int main()
{
  X() += X();
}

正如预期的那样,这会引发编译错误,因为您无法将临时传递给非const引用。

但是,以下内容在ideone上成功编译:

std::string() += std::string();

不应该像我上面的例子那样出错吗?

修改

如果std :: string()将+=定义为成员操作,为什么在这样的用法允许左侧是临时的时候呢?为什么不像我上面那样定义它并避免引用临时问题?

4 个答案:

答案 0 :(得分:6)

C ++规则是您不能将临时绑定到非const引用。但是,您可以在临时对象上调用非const成员函数:如果将operator +=()定义为成员,则可以在对象上调用它。这是如何从临时参考中获取参考的技巧之一,例如:当使用临时std::istringstream读取非基本类型(基本类型由成员读取)时:

std::string word;
if (std::istringstream("hello world") >> std::ws >> word) { ... }

(是的,这个 是一个愚蠢的例子)。

答案 1 :(得分:3)

因为 const

string::operator+=

更改为X& operator+=(const X& y)也会使您的代码编译正常。

修改

我已经回答了问题之后更改了问题,并将X::operator+=的定义更改为friend函数而不是成员函数。确实工作。请注意,std::string::operator+=不是friend,它是std::string的成员函数。

答案 2 :(得分:3)

string& operator+= ( const string& str ); 

感受到差异

答案 3 :(得分:0)

operator+=通常作为成员函数重载,并且可以在临时 rvalues 上调用成员函数(const或其他)。< / p>

如果您将重载更改为成员X& operator+=(const X&),那么您的示例也应该编译。