Конструктор из ссылки на массив не выбран для инициализации списка
Учитывая следующую структуру:
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++. У него нет типа или чего-то еще. Это просто список инициалов. Это только основано на контексте, который мы придаем этому смыслу. В данном случае это не вещь, которая преобразуется в другую вещь... это просто набор инициализаторов для массива.