Clinton
Clinton

Reputation: 23135

C++: References to parameters

The answer to this question points out that you shouldn't return references to parameters, as they may be temporaries which may be out of scope, and will not be preserved if the result is assigned to a reference.

Following that logic, doesn't the following code have a similar problem?

#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;
}

And if so, how should I write the += operator to avoid this problem?

I also imagine there would be problems with the following code in C++11, but I haven't checked it:

#include <iostream>
#include <string>

int main()
{
  for ( char x : std::string("hello") += std::string("world") )
  {
    std::cout << x << std::endl;
  }
}

It would seem as a result you should never return references to function parameters, unless you are prepared to risk undefined behaviour in range based for loops.

Upvotes: 3

Views: 154

Answers (1)

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76788

For cases like this, returning a reference to *this is the expected behavior (this is done to enable Method Chaining). Since this is not a local variable of the function, it will not go out of scope return.

About the second part of your question, the range based for-loop in your case is defined to equivalent to this (§ 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;
    }
}

As you see, the string you iterate over is captured using auto &&, which can bind the const-reference returned by +=.

Edit As Martinho points out in his comment, += returns a non-const reference, so the code shown there is undefined behavior.

Upvotes: 1

Related Questions