如何初始化类如std :: array

时间:2015-09-15 01:43:12

标签: arrays c++11 stl initialization stdarray

我正在尝试为矢量运算编写容器类。对象的大小是静态的:

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一样初始化我的类?

1 个答案:

答案 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?