c++ - 容器std::array的列表初始化需要双括号

标签 c++ curly-braces stdarray list-initialization

用户定义类型的容器的列表初始化不符合我的预期。
请参阅以下代码段:

#include <array>

struct A {
    char C;
    int s;
};

int main(int argc, char * argv[]) {
    A x = {'x'}, y = {'y'};

    std::array<int, 2> i = {1, 2}; // Ok

    std::array<A, 2> a = {x, y}; // Ok
    //std::array<A, 2> b =  { {'x',1000}, {'y',2000} }; // Error: too many initializers!!!
    std::array<A, 2> c = { A{'x',1000}, A{'y',1000} };
    std::array<A, 2> d = {{ {'x',1000}, {'y',1000} }}; // Ok!!
    std::array<A, 2> e = {'x', 2000, 'y', 5000}; // Ok!!
} 

我可以将i初始化为基本数组。只要它们是变量,我就可以使用a进行相同操作。但是我不能在不指定b类型的情况下初始化A,例如c
  • 要初始化std::array而不显式声明A类型,我必须添加另一对花括号。需要大括号背后的逻辑是什么?为什么不能像b那样用列表周围的一对大括号来初始化它?
  • 而且,令人惊讶的是c可以工作,并且只产生两个对象!凭直觉,我希望e会产生错误,因为有4个初始值,最多2个对象,但是编译器正确地填充了A的成员!为什么会这样?
  • 最佳答案

    在考虑任何类型信息之前,将括号嵌套得很深,然后将其与要初始化的对象的结构进行匹配。由于std::array<T,N>必须在中包含一个真正的T[N](而不是一个),因此结构是array内部只有一个对象,即数组。因此,需要使用两个大括号来启动该数组的初始化程序,如果需要整个嵌套集来初始化一个数组元素,或者如果有多个这样的嵌套集,则此方法无效。
    当某些初始化程序子句是表达式甚至A{…}时,此分解将停止,并且初始化程序将用于一个子对象。但是,如果该表达式不能转换为适当的子对象的类型,并且该类型本身是聚合的,则括号省略会发生,并且尽管缺少括号也将后续的初始化程序用于其子对象。当这适用于T[N]对象本身时,可以仅用一层括号初始化array
    因此,简而言之,无论括号是否有效,开放括号都会导致聚合的分解,但是类型不匹配也会导致聚合的分解。

    关于c++ - 容器std::array的列表初始化需要双括号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64954163/

    相关文章:

    c++ - 迭代 boost::variant 中的类型

    c++ - Cryptoauthlib - 匿名 union 只能有非静态数据成员 - 段错误

    c++ - 将 std::array 作为引用参数传递

    arrays - 有没有办法强制对std::array进行完全初始化

    c++ - 读取器/写入器锁 (c++)

    c++ - 内存管理模式

    r - 在ggplot2中添加大括号,然后使用ggsave

    git - Cygwin 的 Git 命令正在从命令中删除大括号。我该如何防止这种情况?

    linux - 在 bash 脚本的大括号中运行命令时的不同结果

    c++ - 将 std::array 转换为 std::vector