C++定义std::pair类型的std::array时为何需要额外的大括号?
问题原因说明
核心本质:std::array是聚合类型
std::array的底层实现是封装了一个固定大小的原生数组,它本身没有自定义构造函数,符合C++聚合类型的定义,必须通过聚合初始化的规则完成构造:
// std::array的实现大致等价于如下结构 template<typename T, std::size_t N> struct array { T __elem[N]; // 内部原生数组成员 // 其余成员函数... };
大括号的层级对应关系
你给出的合法初始化写法的三层大括号分别对应不同的初始化对象:
std::array<std::pair<sf::IntRect, sf::IntRect>, 1> aliens{ // 第一层大括号:初始化整个std::array聚合对象 { // 第二层大括号:初始化std::array内部的原生数组成员`__elem` {sf::IntRect{2,3,1,2}, sf::IntRect{4,1,3,2}} // 第三层大括号:初始化原生数组的第0个元素,也就是`std::pair<sf::IntRect, sf::IntRect>`类型的对象 } };
报错写法的问题所在
当你去掉第二层大括号后,编译器会把传入的两个sf::IntRect对象直接对应到std::array聚合对象的初始化列表:
- 第一个
sf::IntRect会被尝试用来初始化内部原生数组的第0个元素(也就是pair类型),pair需要两个参数才能构造,单个sf::IntRect无法转换为pair,因此触发你看到的类型转换报错 - 第二个
sf::IntRect会被判定为多余的初始化参数,进一步加剧编译错误。
补充说明
如果std::array存储的是基础类型或者可以隐式构造的类型,部分场景下编译器支持省略中间的原生数组初始化大括号,但针对元素是std::pair、自定义结构体这类需要多参数构造的复合类型时,必须明确写出层级对应的大括号避免初始化歧义。
内容的提问来源于stack exchange,提问作者OOPS Studio
相关产品推荐
相关产品推荐

