我有以下代码,这是一个类似于数组的数据结构的简化版:
这个代码在clang 3.3和带有-std=c++11选项的gcc 4.8.1上编译正常。现在我尝试升级gcc,所以我尝试使用4.9.0版本。在这种情况下,第三个例子(ERROR(1))实例化了X的构造函数(ERROR(2)),此时编译器报告错误。
这个例子试图默认初始化数组
如果我添加以下任一形式的另一个默认构造函数,则错误将消失:
但不是。
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和带有-std=c++11选项的gcc 4.8.1上编译正常。现在我尝试升级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{} {}
这个解决方案并不困难,但是你知道谁错了谁对了吗?这样我就知道自己在做什么以及为什么要这么做。
X() : a{} {}
(去掉explicit
)。我认为这与 http://gcc.gnu.org/PR60416 和 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1518 有关。 - Jonathan Wakelystd::array<T,N> a;
而不是T a[N];
并不会改变任何东西。问题仍然存在。 - iavr