2012-02-29 60 views
3

this question的回答指出,不應該返回對參數的引用,因爲它們可能是超出範圍的臨時對象,並且如果將結果分配給引用,則不會保留。C++:對參數的引用

遵循這個邏輯,下面的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; 
    } 
} 

這似乎是你永遠不應該返回引用的功能參數結果,除非您準備在基於循環的範圍內冒未定義的行爲。

回答

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引用。

編輯作爲Martinho在他的評論中指出,+=返回一個非const引用,所以顯示的代碼中有未定義的行爲。

+2

'auto &&'會綁定一個左值引用,因爲那是'operator + ='返回的值。這不會延長臨時的生命週期,而且代碼確實是未定義的行爲。 – 2012-02-29 09:06:40

+0

@ R.MartinhoFernandes:的確,我的錯誤。 – 2012-02-29 09:13:17