Единая инициализация ссылок - PullRequest
18 голосов
/ 01 июля 2011

В настоящее время я пытаюсь понять новую унифицированную инициализацию C ++ 0x. К сожалению, я наткнулся на использование единой инициализации ссылок. Пример:

int main() {
   int a;
   int &ref{a};
}

Этот пример отлично работает:

% LANG=C g++ uniform_init_of_ref.cpp -std=c++0x -o uni -Wall -Wextra
uniform_init_of_ref.cpp: In function `int main()':
uniform_init_of_ref.cpp:3:10: warning: unused variable `ref' [-Wunused-variable]

( Обновление Comeau выдает ошибку для этого примера, поэтому, возможно, gcc не должен скомпилировать ее также)

Теперь, если я использую пользовательский тип данных вместо целого числа, он больше не работает:

class Y
{};

int main()
{
    Y y;
    Y &ref{y};
}

% LANG=C g++ initialization.cpp -std=c++0x -o initialization -Wall -Wextra
initialization.cpp: In function `int main()':
initialization.cpp:9:13: error: invalid initialization of non-const reference of type `Y&' from an rvalue of type `<brace-enclosed initializer list>'
initialization.cpp:9:8: warning: unused variable `ref' [-Wunused-variable]

К сожалению, я не нашел соответствующего раздела в стандартном проекте. Я предполагаю, что я неправильно понимаю использование унифицированной инициализации, поскольку Comeau жалуется на это сообщение:

ComeauTest.c(9): error: reference variable "ref" requires an initializer
      Y &ref{y};

Итак, кто-то из вас может направить меня в правильном направлении?


В случае, если вы хотите знать, почему этот вопрос актуален и почему я не просто использую Y &ref(y): я хотел бы иметь возможность использовать равномерную инициализацию в списке инициализации конструктора:

class X { };

class Y {
    const X& x;

    public:
        Y (const X& xx):
            x{xx}
        {}
};

int main () {
    X x;
    Y y{x};
}

Сбой при появлении того же сообщения об ошибке, что и выше.

Примечание:

  • Я использую LANG=C для включения сообщений об ошибках на английском языке.
  • gcc версия: 4.6.1

1 Ответ

6 голосов
/ 01 июля 2011

Согласно N2672 в пункте 8.5.4.4 должно быть указано:

В противном случае, если T является ссылочным типом, временное значение типа r, на которое ссылается T, инициализируется списком, и ссылка привязывается к этому временному объекту. [Примечание: Как обычно, привязка завершится неудачно, и программа будет неправильно сформирована, если ссылочный тип является lvalue-ссылкой на неконстантный тип. ]

что (если я правильно понимаю) означает равномерную инициализацию ссылок, связывает их с новыми анонимными экземплярами, поэтому мне кажется, что это довольно бесполезно. Это все еще не объясняет, почему один работает, а другой нет; они должны вести себя одинаково (если только Y не имеет некоторых явных конструкторов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...