массив по умолчанию — против списка инициализации

У меня есть следующий код, упрощение массивоподобной структуры:

template<typename T, size_t N>
struct X
{
T a[N];

template<typename... A>
explicit X(A&&... a) : a{std::forward<A>(a)...} { }  // ERROR (2)
};

int main ()
{
X<int,3> x;           // OK
X<X<int,3>,2> y{x,x}; // OK
X<X<int,3>,2> z;      // ERROR (1)
}

Это хорошо компилируется в Clang 3.3 и GCC 4.8.1, оба с -std=c++11, Я пытаюсь обновить gcc, поэтому я сейчас пробую 4.9.0. В этом случае 3-й пример (ERROR (1)) создает экземпляры Xконструктор (ERROR (2)), в этот момент компилятор сообщает

error: converting to 'X<int, 3ul>' from initializer list would use explicit
constructor 'X<T, N>::X(A&&...) [with A = {}; T = int; long unsigned int N = 3ul]

Этот последний пример пытается инициализировать массив по умолчанию z и так же включенные в него массивы; однако, если я правильно понимаю, здесь gcc по существу говорит, что включенные массивы инициализируются списком {}, что недопустимо, поскольку конструктор является явным.

Ошибка исчезнет, ​​если я добавлю другой конструктор по умолчанию любой из следующих форм:

explicit X() {}
explicit X() : a() {}

но не

explicit X() : a{} {}

Этот обходной путь не сложен, но есть идеи, кто не прав, а кто прав, просто чтобы я знал, что я делаю и почему?

3

Решение

Это ошибка GCC, PR 60417.

Старшее изменение для PR 54835 был предназначен для реализации предложенного C ++ комитета направления для исправления основной вопрос 1518. К сожалению, это изменение нарушает некоторые действительные программы на C ++ 03, как показано в первом примере в PR 60417. Исправление было зафиксировано для PR 60417, но оно обрабатывает только некоторые случаи. В частности, это не исправляет случай, когда инициализация списка массив типов с явными конструкторами, как в этом вопросе.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]