У меня есть следующий код, упрощение массивоподобной структуры:
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{} {}
Этот обходной путь не сложен, но есть идеи, кто не прав, а кто прав, просто чтобы я знал, что я делаю и почему?
Это ошибка GCC, PR 60417.
Старшее изменение для PR 54835 был предназначен для реализации предложенного C ++ комитета направления для исправления основной вопрос 1518. К сожалению, это изменение нарушает некоторые действительные программы на C ++ 03, как показано в первом примере в PR 60417. Исправление было зафиксировано для PR 60417, но оно обрабатывает только некоторые случаи. В частности, это не исправляет случай, когда инициализация списка массив типов с явными конструкторами, как в этом вопросе.
Других решений пока нет …