C ++:参数参考

时间:2012-02-29 08:30:28

标签: c++ reference c++11

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循环的范围内冒未定义的行为。

1 个答案:

答案 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引用,因此显示的代码是未定义的行为。