左值初始化失败

时间:2013-10-12 07:02:49

标签: c++ string gcc c++11

“C ++编程语言第4版”中的一些示例代码让我感到困惑。这是我的测试用例。

环境 gcc版本4.6.3(Debian 4.6.3-14 + rpi1),其中-std = c ++ 0x

  • 代码1 string var {"Cambridge"}; string& r1 {var}; 编译失败
  • Code2 string var {"Cambridge"}; string& r1 = var; 编译成功
  • Code3 string var {"Cambridge"}; string&& r1 {var}; 编译成功
  • Code1编译失败, 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
  • 根据书籍,Code1应该没问题。第7.7.2节因为var是左值,但为什么code1不起作用,但code3在我的情况下工作?

1 个答案:

答案 0 :(得分:3)

它失败了,因为它试图将右值绑定到nonconst左值引用。

  

8.5.4列表初始化

     

[#3]

     

- 否则,如果T是引用类型,则为该类型的 prvalue temporary   由T引用的是列表初始化的,引用是   绑定到那个临时的。 [注意:像往常一样,绑定会失败   如果引用类型是非const类型的左值引用,则程序格式错误。 - 结束说明]

选中此示例以验证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 &行为的原因这样。