默认初始化std :: array?
用C ++ 11 std::array
,我有保证std::array<T, N> x;
会默认初始化数组的所有元素?
编辑 :如果没有,是否有一个语法,将所有数组(包括零大小的数组)初始化所有元素的默认值?
编辑 :在cppreference ,默认的构造函数描述说:
(constructor) (implicitly declared) (public member function) default-constructs or copy-constructs every element of the array
所以答案可能是肯定的。 但是我想根据标准或未来标准来确定。
根据定义,默认初始化是在没有指定其他初始化时发生的初始化; C ++语言保证你没有提供显式初始化的任何对象将被默认初始化(C ++ 11§8.5/ 11)。 这包括std::array<T, N>
和T[N]
types的对象。
请注意,有些types的默认初始化没有任何效果,并且使对象的值不确定:任何非类,非数组types(§8.5/ 6)。 因此,具有这种types的对象的默认初始化数组将具有不确定的值,例如:
int plain_int; int c_style_array[13]; std::array<int, 13> cxx_style_array;
c样式数组和std::array
都用不确定值的整数填充,就像plain_int
具有不确定的值一样。
是否有一种语法可以在所有数组(包括零大小数组)上初始化所有元素为默认值?
我猜测,当你说“他们的默认值”,你的意思是“初始化所有元素T{}
”。 这不是默认初始化 ,它是值初始化 (8.5 / 7)。 您可以通过给每个声明一个空的初始化程序,在C ++ 11中很容易地请求值初始化:
int plain_int{}; int c_style_array[13]{}; std::array<int, 13> cxx_style_array{};
这将依次重新初始化所有的数组元素,导致plain_old_int
,以及这两种数组的所有成员被初始化为零。
默认初始化是标准中的一个术语,可能意味着根本不需要初始化,所以你可能意味着零初始化 。
在cppreference.com上的描述实际上有点误导。 std::array
是一个聚合类,如果元素types是原始types,它是POD:“普通旧数据”,语义紧密匹配C语言。 std::array< int, N >
的隐式定义的构造函数是一个毫无意义的构造函数。
像std::array< int, 3 >()
或std::array< int, 3 > x{}
这样的提供归零值的语法不会通过调用构造函数来实现。 获取零值是C ++ 11§8.5/ 8中指定的值初始化的一部分:
为了初始化Ttypes的对象,意味着:
– 如果T是没有用户提供或删除默认构造函数的(可能是cv-qualified)类types,那么该对象是零初始化的,如果T有一个不平凡的默认构造函数,则该对象被默认初始化;
std::array
没有用户提供的默认构造函数,所以它被初始化为零。 它有一个隐式定义的默认构造函数,但它是微不足道的,所以它不会被默认初始化。 (但这并没有什么区别,因为定义的简单初始化在运行时没有任何影响。)
如果不是,是否有一种语法可以在所有数组(包括零大小数组)上初始化所有元素为默认值?
C风格的数组和std::array
都是聚合,并且完全初始化任何聚合的方式是语法= {}
。 这从C ++ 98开始工作。 请注意,C风格的数组不能有0的范围,并且sizeof (std::array< X, 0 >)
不为零。
T x[N];
和std::array<T, N> x;
默认初始化数组的每个元素。
例如,如果T = std::string
,则每个元素都将是一个空string。 如果T
是没有默认构造函数的类,则两者都将无法编译。 如果T = int
,则每个元素都将具有不确定的值(除非该声明恰好在命名空间范围内)
首先,T x [N]默认初始化元素,但标量typesT的默认初始化实际上什么都不做。 上面也适用于std :: array x。 我认为你需要的是列表初始化。