我正在尝试为矢量运算编写容器类。对象的大小是静态的:
template<typename T, unsigned N>
class vec{
T data[N] = {0};
public:
vec(std::initializer_list<T> ini){
std::copy(ini.begin(), ini.end(), data);
}
}
这是我有多远。
但是我测试了std :: array类进行比较,我注意到如果初始化列表是长或短,它会以某种方式产生静态断言。
std::array<float, 2> a = {1, 2, 3, 4} <- instant error message from the visual studio ide
在我的班级中,我必须在运行时检查初始化列表的长度。
我假设,std :: array类以某种方式管理它,使用初始化列表表示法直接初始化数据而不使用std :: initializer_list类。
是否可以像std :: array一样初始化我的类?
答案 0 :(得分:2)
std::array是一个聚合,因此它使用aggregate initialization。在聚合初始化期间提供过量元素是不正确的并且需要诊断。编译器至少必须提供警告,gcc和clang都会使这个错误。因此,如果你使你的类成为聚合,那么你可以让它以与std :: array相同的方式工作。请注意,C ++ 11中的in class member initializers makes your class a non-aggregate,但C ++ 14中没有。
我们可以通过转到草案C ++ 11标准部分@Autowrited
[array.overview] 看到它是一个聚合:
数组是一个聚合(8.5.1),可以用它初始化 语法
23.3.2.1
其中initializer-list是最多包含N个元素的逗号分隔列表 其类型可转换为T.
和第array<T, N> a = { initializer-list };
部分 [dcl.init.aggr] 涵盖了聚合初始化并说:
如果初始化子条款的数量,则初始化列表格式不正确 超过要初始化的成员或元素的数量。
标准草案规定了一个可能的实施方案,其缩写为最低限度:
8.5.1
标准草案中有一条说明:
成员变量elems仅用于展示,以强调该数组是类聚合。 名称elems不是数组接口的一部分
这是一个聚合,如果提供了多余的元素,则同时使用gcc和clang都会出错。
另见What are Aggregates and PODs and how/why are they special?。