2013-05-11 41 views
6

我知道在C++ 03中,非const引用不能綁定到右值。在C++ 11中將非常量左值引用綁定到右值是否有效?(已修改)

T& t = getT();是無效的,在C++ 11中,我們可以這樣做:T&& t = getT();但上面的代碼應該如何在C++ 11中工作?

我測試的代碼下面VS11:

Foo getFoo() { 
    return Foo(); 
} 

void fz(Foo& f) { 
} 

int getInt() { 
    return int(); 
} 

void iz(int& i) { 
} 

int main() { 
    { 
    Foo& z = getFoo(); //ok 
    fz(getFoo()); //ok 

    int& z2 = getInt(); //error: initial value of reference to non-const must be an lvalue 
    iz(getInt()); //same as above 
    } 
} 

Foo是一個自定義類,我不理解爲什麼前兩個行compiles.The臨時由z引用在內的端部被破壞主要範圍。標準是否對此有所說明?

class Foo { 
public: 
    Foo() { 
    std::cout << "constructed\n"; 
    } 
    ~Foo() { 
    std::cout << "destructed\n"; 
    } 
}; 

我剛纔看到一個類似的問題:One VS2010 bug ? Allowing binding non-const reference to rvalue WITHOUT EVEN a warning?

+4

有意思的是幾*的Objective-C或Java程序員如何*詢問像面向語言的深奧的問題「是不是有效綁定右值到非常量左值引用...?「或者不得不關注像「臨時引用......在內部作用域結束時被破壞」的東西。只是說';) – paulsm4 2013-05-11 03:55:17

+0

你可以發佈你如何定義Foo。 – Gisway 2013-05-11 04:05:00

+0

約束力的規則並沒有改變WRT左值引用AFAIK – 2013-05-11 04:34:13

回答

5

應該在C++ 11中工作嗎?

不,不應該。

Foo是一個自定義類,我不明白爲什麼前兩行編譯

只用MSVC編譯。 MSVC有一個(可以說是有用的)編譯器擴展,允許將用戶定義類型的左值綁定到右值,但是標準本身禁止這樣做。例如,請參閱this live example,其中GCC 4.7.2拒絕編譯您的代碼。

標準是否對此有任何說明?

確實如此。根據第8.5段。在C++ 11標準的3/5:

的參考輸入「cv1 T1」由類型「cv2 T2」的表達如下初始化:

- 如果參考是一個左值和參考初始化表達

- 是一個左值(但不是位字段),以及「cv1 T1」是參考兼容「cv2 T2」或

- 具有類別類型(即,T2是類別類型),其中T1T2不是引用相關的,可以是 隱式轉換爲類型爲「cv3 T3」的左值,其中「cv1 T1」與引用兼容「cv3 T3」 [...],

那麼參考結合到初始化表達式左值在所述第一殼體和所述左值結果在第二種情況下(轉換,或者在任何一種情況下 ,至對象的適當基類子對象 )。 [...]

[...]

- 否則,應參考是一個左值參照非易失性const的類型(即,CV1應 常數),或參考應是一個右值參考。 [例:

double& rd2 = 2.0; // error: not an lvalue and reference not const 
int i = 2; 
double& rd3 = i; // error: type mismatch and reference not const 

末端例如]

0

不,你不能綁定一個臨時的非const左值參考。

T f(); 

T& t1 = f(); // won't compile 
const T& t2 = f(); // OK 
T&& t3 = f(); // OK 

這是一項安全功能。無論如何,即將死亡的左值變爲臨時值很可能是邏輯錯誤,所以語言不允許這樣做。

注意的是,由於RVO比做法:

T&& t3 = f(); 

T t3 = f(); 

是equivilent。

相關問題