2013-10-12 256 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