我想像这样初始化数组:
#include <string>
#include <array>
struct r{
std::string name;
int x;
};
int main()
{
std::array<r, 2> a { {"weklrj", 3}, {"lekw", 2} };
}
但它给出了这个错误:
test.cpp: In function ‘int main()’:
test.cpp:12:50: error: too many initializers for ‘std::array<r, 2>’
12 | std::array<r, 2> a { {"weklrj", 3}, {"lekw", 2} };
| ^
如果我再添加一个这样的括号,那么一切都会好起来的:
#include <string>
#include <array>
struct r{
std::string name;
int x;
};
int main()
{
std::array<r, 2> a {{ {"weklrj", 3}, {"lekw", 2} }};
}
问题:这些额外的括号是做什么用的?事实上,根据第一个变体中的逻辑,外部是统一初始化,内部是每个单独结构的指定,一切都应该工作。
std::array<T, N>是具有一个公共视图字段的类T некоторое_имя[N];(至少对于N > 0)。因此,在 中
std::array<r, 2> a {{ {"weklrj", 3}, {"lekw", 2} }};,外括号代表整个类std::array,下一个括号代表这个数组,两对内括号代表这个数组的元素。还有一点更有趣。为什么
std::array<int, 3> arr{1, 2, 3};它可以与一对括号一起使用?Cppreference说:
简单来说,您只能从最嵌套的括号开始删除括号。
示例:如果我们有
那么我们可以删除的第一步只是最嵌套的括号对。我们得到:
接下来,我们可以再次删除嵌套最多的括号:
但是,当然,只有在中间没有省略初始化程序时,这种括号的删除才有效。例如,它
std::array<r, 2> a{{ {"weklrj"}, {"lekw"} }};编译,但std::array<r, 2> a{{"weklrj", "lekw"}};它没有编译,因为编译器会尝试将第二个字符串转换为inty。当你写
您初始化结构,更具体地说,将其字段
name和x值分配给"строка"和3。你什么时候写:
它看起来像这样:该结构
array似乎有 2 个您初始化的字段элемент1和элемент2,这是不正确的。在结构体的源代码中
array,有这一行:value_type在你的情况下,结构在哪里r,_Nm是大小2。那就是你添加{}简单地初始化这个数组。数组
std :: array被实现为结构。它只有两个构造函数。默认和实际。大量花括号使编译器难以自动确定表示的类型。用实际类型记录
r帮助编译器确定类型
r,并调用“聚合初始化”构造函数。以及使用一个参数调用构造函数
自动提供一种调用“聚合初始化”构造函数的方法。
使用未指定类型的结构中的元素调用构造函数
导致不确定性:如果需要做“聚合初始化”,那么参数太多了。并且由于在花括号之前没有指定类型,因此无法确定这是一个结构
r还是另一个。