2013-10-12 254 views
6

「The C++ Programming Language 4th Edition」中的一些示例代碼讓我感到困惑。這是我的測試用例。左值初始化失敗

的Env gcc版本4.6.3(Debian的4.6.3-14 + rpi1)與-std =的C++ 0x

  • 代碼1string var {"Cambridge"}; string& r1 {var};編譯失敗
  • 代碼2string var {"Cambridge"}; string& r1 = var;編譯成功
  • 代碼3string var {"Cambridge"}; string&& r1 {var};編譯成功
  • 代碼1編譯與g++ -g -DLINUX -std=c++0x -c src/dummy.cpp -o src/dummy.o src/dummy.cpp: In function ‘int main(int, char**)’: src/dummy.cpp:26:17: error: invalid initialization of non-const reference of type ‘std::string& {aka std::basic_string<char>&}’ from an rvalue of type ‘<brace-enclosed initializer list>’ make: *** [src/dummy.o] Error 1
  • 代碼1失敗應該是根據書確定。 7.7.2節,因爲var是一個左值,但爲什麼code1不起作用,但code3在我的情況下工作?
+1

看起來像GCC(包括4.8)中的錯誤,鐺接受版本1就好了。 –

+3

您遇到[DR1288](http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1288)。希望最近的編譯器能夠實現提出的解決方案,而不是標準化的缺陷。 – dyp

回答

3

它失敗了,因爲它試圖將右值綁定到非常量左值引用。

8.5.4列表初始化

[#3]

- 否則,如果T是引用類型,用T引用的類型 的prvalue臨時是列表 - 初始化,並且參考是 綁定到那個臨時。 [注意:與往常一樣,綁定將失敗 ,如果引用類型是非常量類型的左值引用,則該程序不合格。 - 注完]

檢查這個例子中,以驗證r1綁定到不同的對象

#include <string> 
#include <iostream> 

int 
main() { 
    std::string var {"Cambridge"}; 
    const std::string& r1 {var}; 
    const std::string& r2 (var); 

    var.clear(); 

    std::cout << "var = " << var << std::endl; 
    std::cout << "r1 = " << r1 << std::endl; 
    std::cout << "r2 = " << r2 << std::endl; 
} 

和對比度,爲r2

PS。現在的問題是,爲什麼下面沒有根據上述考慮失敗:

int x; 
int &y { x }; 

標準說(在同一個地方同上,但在下一項):

- 否則,如果初始化器列表具有單個元素,則從該元素初始化該對象或參考;

該條款明確提到參照,換句話說,初始化參考的是不是一個單一的條款中所描述的,但也有幾個可能性(在條款的順序也許試過嗎?),這可以解釋爲什麼int &的行爲本辦法。

+0

感謝您的回覆。那麼這是否意味着該書的代碼是錯誤的?它試圖說這是一個正確的演示代碼'string&r1 {var}; //左值引用,將r1綁定到var(左值)'書的第7.7.2節 –

+0

您能否給我一些關於您的編譯器的信息?您是否使用示例代碼編譯獲得了相同的「編譯錯誤」? –

+0

GCC 4.8.1在這裏使用。是的,我認爲這本書是錯誤的,還有另外一個'string && rr2 {var};'應該可以工作。 – chill