c++ - 使用声明中的元素类型隐式初始化 std::array

标签 c++ initialization language-lawyer stdarray aggregate-initialization

如下code我正在尝试初始化数组(原始 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_array我可以指定S只有一次。但尝试同样的 std::array不起作用(请参阅评论的 std_array_no_type )。我必须指定 S仅针对初始化列表中的第一个元素键入每个或(这也是问题的有趣部分)(请参阅 std_array_one_type_only )。

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

最佳答案

关于第一个问题,

So, is there a way to define an initialized std::array object using the type S only once?

您可以添加另一对 {},因为 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

关于第二个问题,

And why single explicit type S allows std_array_one_type_only to be compiled?

aggregate initialization ,嵌套初始化列表的大括号可以省略,

If the aggregate initialization uses copy- (until C++14)list-initialization syntax (T a = {args..} or T a {args..} (since C++14)), the braces around the nested initializer lists may be elided (omitted), in which case as many initializer clauses as necessary are used to initialize every member or element of the corresponding subaggregate, and the subsequent initializer clauses are used to initialize the following members of the object.

给定

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} 来初始化以下成员底层数组的。

关于c++ - 使用声明中的元素类型隐式初始化 std::array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57390870/

相关文章:

c++ - SFINAE 在 VS2017 上的编译错误

c++ - 全局变量 "things"和 "single"?

pointers - 如何在 Go 中初始化一个指向结构的指针类型?

c++ - 是否在三元运算符 corect 的 else 部分中增加映射迭代器?

c++ - 数组到指针转换期间的临时物化

c++ - 允许 `this->` 访问依赖基类的成员的规则是什么?

c++ - 使用不带回调 C++ 的函数

c++ - 有没有办法从插槽中删除特定信号

swift - 如何在 Swift 中的两个初始化函数之间共享一个初始化函数?

swift - 下面这段代码中指定初始化和便利初始化有什么区别