this question的答案指出你不应该返回对参数的引用,因为它们可能是超出范围的临时值,并且如果将结果分配给引用则不会保留。< / p>
遵循该逻辑,以下code是否有类似的问题?
#include <iostream>
class T
{
public:
T& operator+=(const T& t) { this->x += t.x; return *this; }
T(int x) : x(x) {}
int x;
~T()
{
std::cout << "My value is " << this->x << " and I'm dead." << std::endl;
this->x = -999;
}
};
int main()
{
const T& t = (T(2) += T(3));
std::cout << t.x << std::endl;
}
如果是这样,我应该如何编写+=
运算符以避免此问题?
我还想象C ++ 11中的以下代码会出现问题,但我没有检查过:
#include <iostream>
#include <string>
int main()
{
for ( char x : std::string("hello") += std::string("world") )
{
std::cout << x << std::endl;
}
}
结果看起来你永远不应该返回对函数参数的引用,除非你准备冒险在基于for循环的范围内冒未定义的行为。
答案 0 :(得分:1)
对于这样的情况,返回对*this
的引用是预期的行为(这样做是为了启用Method Chaining)。由于this
不是函数的局部变量,因此它不会超出范围返回。
关于问题的第二部分,您的案例中基于for循环的范围被定义为等同于此(第6.5.4节[stmt.ranged]):
{
auto && __range = std::string("hello") += std::string("world");
for ( auto __begin = begin(__range),
__end = end(__range);
__begin != __end;
++__begin ) {
char x = *__begin;
std::cout << x << std::endl;
}
}
如您所见,使用auto &&
捕获您迭代的字符串,+=
可以绑定+=
返回的const-reference。
编辑正如Martinho在评论中指出的那样,{{1}}会返回一个非const引用,因此显示的代码是未定义的行为。