Конструктор из ссылки на массив не выбран для инициализации списка

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

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 ответ

Решение

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

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 означает, что мы ищем конструктор, который мы можем вызвать с одним аргументом, который мы инициализируем 1, 2 ,3, 4,

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


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

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

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

Другие вопросы по тегам