Почему это не работает? (скобка-инициализация ссылок) - PullRequest
0 голосов
/ 12 января 2019
#include <array>

int main()
{
    struct A
    {
        unsigned char l;
        std::array<char, 12> c;
    };

    const A a = {1, "t"}; // OK
    const A& ar = {1, "t"}; // error: invalid initialization of reference of type 'const main()::A&' from expression of type '<brace-enclosed initializer list>'
}

(gcc 8.2, -std = c ++ 17)

Этот вопрос говорит об ошибке в GCC, но она старая (7 лет назад).

Обратите внимание, что меня не волнует продление срока службы, я фактически передаю временное непосредственно в функцию для использования, а не храню ее, но я попытался сделать пример чистым.


Edit:

  • Я не могу сделать пример меньше. В частности, это связано с array<char>.
  • Добавление дополнительных скобок вокруг "t" и по-прежнему не удается.
  • Что-то, что работает, разбивает строковый литерал на символы:

    const A& ar = {1, {'a', 'b'}}; // works
    

1 Ответ

0 голосов
/ 12 января 2019

Первое, что следует заметить, это то, что инициализатор {1, "t"} использует brace elision для инициализации субагрегата A.c, что означает, что литерал "t" используется для непосредственной инициализации внутреннего массива что std::array имеет место. В этом случае этот массив будет выглядеть как char data[12].

Это сводится к тому, что мы инициализируем ссылку на const A с помощью фигурного списка, содержащего элемент, который инициализирует массив элементов .

Это будет несколько эквивалентно:

struct S {
    char const data[2];
};
S const& s = {"t"}; // fail for gcc

В GCC уже есть отчет об ошибке .

Вы уже предоставили обходной путь в разделе комментариев. Просто инициализируйте ссылку как:

const A& ar = A{1, "t"}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...