2013-10-12 4 views
6

Некоторые примеры кода из «Язык программирования C++ 4th Edition» заставляет меня запутываться. Вот мои тестовые примеры.Ошибка инициализации lvalue

конв 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;Compiling Succeed
  • Код3string var {"Cambridge"}; string&& r1 {var};Компиляция Succeed
  • 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 является lvalue, но почему код1 не работает, но code3 работает в моей ситуации?
+1

Похож на ошибку в GCC (включая 4.8), Clang принимает версию 1 просто отлично. –

+3

Вы столкнулись с [DR1288] (http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1288). Надеемся, что последние компиляторы будут выполнять предлагаемую резолюцию вместо стандартизованного дефекта. – dyp

ответ

3

Он терпит неудачу, потому что пытается привязать значение r к ссылке nonconst lvalue.

8.5.4 Список инициализация

[# 3]

- В противном случае, если Т представляет собой тип справки, prvalue временного типа , на который ссылается Т list- инициализируется, а ссылка - , связанная с этим временным. [Примечание. Как обычно, привязка завершится с ошибкой , и программа плохо сформирована, если ссылочный тип является ссылкой lvalue на неконстантный тип. - конец примечание]

Проверьте этот пример, чтобы убедиться, что 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}; // lvalue reference, bind r1 to var (lvalue) 'Раздел 7.7.2 книги –

+0

Не могли бы вы дать мне некоторую информацию о вашем компиляторе? Вы получили ту же «ошибку компиляции» с компиляцией кода примера? –

+0

GCC 4.8.1 используется здесь. Да, я думаю, что книга ошибочна, и есть еще одна строка '&& rr2 {var};' должна работать. – chill

Смежные вопросы