Конструктор из ссылки на массив не выбран для инициализации списка - PullRequest
0 голосов
/ 04 февраля 2019

Учитывая следующую структуру:

struct A {
    template<typename T, std::size_t N>
    A(T const(&array)[N]) {}

    template<typename T, std::size_t N>
    A& operator=(T const(&array)[N]) { return *this; }
 };

Код:

// a is of type A
a = {1, 2, 3, 4};

компилируется просто отлично, поскольку std::initialiser_list неявно преобразуется в ссылку на массив.

Однако

A a {1, 2, 3, 4};
A a = {1, 2, 3, 4};

не удается скомпилировать как с Clang, так и с GCC.Он компилируется, когда я добавляю конструктор, который принимает std::initialiser_list<T>.

Чего мне не хватает?

1 Ответ

0 голосов
/ 04 февраля 2019

Вам просто нужны дополнительные скобки или парены:

A a{{1, 2, 3, 4}}; // ok
A b({1, 2, 3, 4}); // ok

Причина в том, что внешние скобки / парены предназначены для A, а во внутренних скобках - для объекта array, который выПеречень-инициализация.

При назначении вам не нужны лишние скобки или скобки, потому что они просто подразумеваются вызовом функции:

a = {1, 2, 3, 4};

эквивалентно:

a.operator=({1, 2, 3, 4});

Больше или меньше.

Он компилируется, когда я добавляю конструктор, который принимает std::initialiser_list<T>.

Чтобы понять, как работает инициализация списка.Когда вы пишете A a{1, 2, 3, 4}, мы сначала ищем какой-то std::initializer_list<T> конструктор (которого у нас еще нет, и поэтому не можем его найти), а затем ищем конструктор, который мы можемвызов с четырьмя аргументами (которых не существует).Добавление дополнительных () s или {} s означает, что мы ищем конструктор, который мы можем вызвать с один аргумент, который мы инициализируем с 1, 2 ,3, 4.

Как только вы добавитеконструктор std::initializer_list<T>, теперь это жизнеспособный кандидат для этой первой фазы инициализации.

Обратите внимание, что это:

компилируется просто отлично, поскольку std::initialiser_list неявно преобразуется в ссылку на массив.

не правильно.std::initializer_list нигде в этом вопросе нет.{1, 2, 3, 4} забавная вещь в C ++.У него нет типа или чего-то еще.Это просто braced-init-list .Это только основано на контексте, который мы придаем этому смыслу.В данном случае это не то, что преобразуется в другое ... это просто набор инициализаторов для массива.

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