2

在下面的代码中,我试图初始化数组(原始 C-classic 和std::array),以最小化元素类型的使用,即S

#include <array>

struct S { unsigned u; int i; };

auto std_array = std::array<S, 3>{
    S{0U, 0},
    S{1U, 1},
    S{2U, 2}
};

S raw_array[] = {
    {0U, 0},
    {1U, 1},
    {2U, 2}
}; 

/*  // compile error: excess elements in struct initializer
std::array<S,3> std_array_no_type = {
    {0U, 0},
    {1U, 1},
    {2U, 2}
}; 
*/

std::array<S,3> std_array_one_type_only = {
    S{0U, 0},
    {1U, 1},
    {2U, 2}
}; 

int main() {}

使用raw_arrayI 只能指定S一次。但是尝试相同的std::array方法不起作用(请参阅评论std_array_no_type)。我必须S只为初始化列表中的第一个元素指定每个 or(这也是问题的一个有趣部分)的类型(请参阅 参考资料std_array_one_type_only)。

那么,有没有办法只使用一次类型来定义一个初始化std::array对象S?如果不是,根据标准的哪个条款?为什么S允许std_array_one_type_only编译单个显式类型?

4

1 回答 1

3

关于第一个问题,

那么,有没有办法只使用一次类型来定义一个初始化std::array对象S

您可以添加另一对{}, 因为std::array实际上包含一个底层数组。

std::array<S,3> std_array_one_type_only = {{{0U, 0}, {1U, 1}, {2U, 2}}}; 
//                                        ^                           ^ for std::array
//                                         ^                         ^  for underlying array
//                                          ^     ^                     for the 1st element of underlying array
//                                                   ^     ^            for the 2nd element of underlying array
//                                                            ^     ^   for the 3rd element of underlying array

关于第二个问题,

为什么S允许std_array_one_type_only编译单个显式类型?

聚合初始化中,嵌套初始化列表的大括号可以省略,

如果聚合初始化使用copy- (until C++14)列表初始化语法T a = {args..} or T a {args..} (since C++14)(随后的初始化子句用于初始化对象的以下成员。

给定

std::array<S,3> std_array_no_type = {{0U, 0}, {1U, 1}, {2U, 2}}; 
//                                  ^                         ^  for std::array
//                                   ^     ^                     for underlying array

第一个{0U, 0}将尝试用于初始化整个底层数组,然后导致错误,如初始化程序中的多余元素,因为std::array不包含任何进一步的子对象。

给定

std::array<S,3> std_array_no_type = {S{0U, 0}, {1U, 1}, {2U, 2}}; 
//                                  ^                          ^ for std::array
//                                    ^     ^                    for the 1st element of underlying array
//                                             ^     ^           for the 2nd element of underlying array
//                                                      ^     ^  for the 3rd element of underlying array

S{0U, 0}不能用于初始化底层数组(不满足聚合初始化的风格),那么它将用于初始化底层数组的第一个元素,即应用上面的大括号省略规则,然后以下{1U, 1}{2U, 2}用于初始化基础数组的以下成员。

于 2019-08-07T09:17:12.070 回答