数组默认初始化与列表初始化



我有下面的代码,一个类似数组结构的简化:

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{} {}

这个解决方法并不难,但是知道谁是错的,谁是对的吗,这样我就知道我在做什么,为什么?

这是一个GCC bug, PR 60417。

PR 54835的旧更改旨在实现c++委员会提议的修复核心问题1518的方向。不幸的是,这种改变破坏了一些有效的c++ 03程序,如PR 60417中的第一个示例所示。修复了PR 60417,但它只处理了一些情况。特别是,它不能修复使用显式构造函数对类型数组进行列表初始化的情况,就像这个问题一样。

相关内容

  • 没有找到相关文章

最新更新