问题 关于std :: array fill的设计决策


std::array 在C ++ 11中是一个有用的类,它在C堆栈数组上提供C ++ Container接口。

但为什么呢 std::array 没有大多数容器的典型填充构造函数?相反,它有一个方法 fill

有什么理由吗? std::array 在这方面STL容器是独一无二的?


2449
2017-08-09 20:37


起源

因为否则std :: array将不再是POD。 - Thomas Petit
我认为C ++ 11放宽了POD的定义 - Channel72
@ Channel72:POD: “POD结构是一个非联合类,它是一个 琐碎的阶级 和标准布局类[...]“。琐碎的课程: “一个普通的类是一个有默认构造函数(12.1)的类,没有 非平凡的默认构造函数,并且可以轻易复制。“ 然而, std::array 是一个聚合,并且必须遵循类似的规则(参见Borgleader的回答)。 - Zeta


答案:


从第23.3.2.1节:

数组是可以使用语法初始化的聚合(8.5.1)   array a = {initializer-list};

如果有效的话 std::vector 它不再是POD了。另外来自同一部分:

应满足总量(8.5.1)的条件。

这些条件是:

聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有大括号或相等的初始化器   对于非静态数据成员(9.2),没有私有或受保护的非静态数据成员(第11条),   没有基类(第10条),也没有虚函数(10.3)。


6
2017-08-09 20:45





是; std::array 意味着是一个聚合(C ++11§8.5.1),因此可以在可以使用普通数组的情况下使用尽可能多的上下文。聚合可以没有显式构造函数或析构函数。


5
2017-08-09 20:44





每个人都很好地解释了“为什么”我认为,所以我会提出一个解决方案建议,它应该编译成与本机构造函数一样好:

template< typename T, std::size_t n > std::array<T,n> filledArray( const T& v ) {
    std::array<T,n> r;
    r.fill( v );
    return r;
}

auto arr = filledArray<int,4>( 7 );

3
2017-08-09 20:51



嗯,没有使用for-range循环的任何原因?只是好奇。 - Zeta
或者 fill 会员功能? - Benjamin Lindley
@BenjaminLindley好点! - Dave
@Zeta也是因为我一直忘记它存在。改用了 fill 因为它更有意义,更有可能进行优化。 - Dave
@Dave:完全忘了 fill() 在讨论POD和聚合时,doh。 - Zeta