I have the following code, a simplification of an array-like structure:
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)
}
This is compiling fine in clang 3.3 and gcc 4.8.1, both with -std=c++11. I am trying to upgrade gcc, so I now try 4.9.0. In this case, the 3rd example (ERROR (1)) instantiates X's constructor (ERROR (2)), at which point the compiler reports
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]
This last example attempts to default-initialize array z and so also its included arrays; however, if I get this right, here gcc essentially says that the included arrays are being list-initialized by {}, which is not allowed since the constructor is explicit.
The error is gone if I add another default constructor of either of the following forms:
explicit X() {}
explicit X() : a() {}
but not
explicit X() : a{} {}
This workaround is not difficult, but any idea who's wrong and who's right, just so I know what I'm doing and why?
X() : a{} {}(without theexplicit). I think this is related to gcc.gnu.org/PR60416 and open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1518std::arrayand get the same functionality without reinventing the wheel :-Pstd::array<T,N> a;instead ofT a[N];does not change anything. The problem remains.