我有以下代码,简化了类似数组的结构:
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。在这种情况下,第三个示例(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{} {}
这种解决方法并不困难,但任何想法谁是错的谁是对的,只是这样我知道我在做什么以及为什么?
答案 0 :(得分:3)
这是一个GCC错误,PR 60417。
PR 54835的旧版更改旨在实现C ++委员会提出的修复core issue 1518的方向。不幸的是,这个更改打破了一些有效的C ++ 03程序,如PR 60417中的第一个示例所示。修复程序已针对PR 60417提交,但它仅处理某些情况。具体来说,它没有修复使用显式构造函数初始化类型数组的情况,如本问题所示。