std :: array类型初始化

时间:2016-05-30 16:40:50

标签: c++ templates aggregate-initialization

使用std::array,您可以像这样初始化它:

std::array<int,5> myArray = {1,2,3,4,5};

如果我试图创建自己的数组类,我将如何做类似的事情?

2 个答案:

答案 0 :(得分:4)

std::array依赖于aggregate initialization(初始化struct的 C方式),基本上这是有效的c ++:

struct A {
    int values[2];
    size_t size;
};

A a = {{42, 44}, 2U}; // No constructor involved
//     |         |--- a.size
//     |--- a.values

现在,如果您删除size属性,则会获得:

struct A {
    int values[2];
};

A a = {{42, 44}}; // Valid!

但是c ++给你一些名为 brace-elision 的东西,我们允许你省略内括号,所以:

A a = {42, 44}; // Still valid!

现在,只需将A作为模板:

template <typename T, size_t N>
struct A {
    T data[N];
};

A<int, 2> a = {{42, 44}};

请注意,这不会使用用于std::vectorstd::list等的initializer_list

另请注意:

A<int, 2> a1{42, 44}; // Not valid prior to c++14
A<int, 2> a2{{42, 44}}; // Ok even for c++11

请注意,无论您默认使用哪个版本,clang都会发出警告。

std::array的极简主义版本可能如下所示:

template <typename T, size_t N>
struct my_array {

    T _data[N];

    T& operator[] (size_t i) { return _data[i]; }
    const T& operator[] (size_t i) const { return _data[i]; }

    constexpr size_t size () const { return N; }

    T* begin () { return _data; }
    const T* begin () const{ return _data; }
    T* end () { return _data + size(); }
    T* end () const { return _data + size(); }

};

请注意,标准std::array比这更多(大量typedef s,其他methods,有很多重载,......),但是这个是一个让你入门的小基地。

另请注意,_data必须为public,以便聚合初始化可以正常工作(如果您有private / {{1}则无效成员!)。

答案 1 :(得分:1)

这是一个支持使用元素列表进行初始化的简单实现:

//template class 'array' takes 'T' (the type of the array) and 'size'
template<typename T, std::size_t size>
class array
{
public:
    //This is the concept of initializer lists (wrapper around variadic arguments, that
    //allows for easy access)
    array(std::initializer_list<T> list)
    {
        //Loop through each value in 'list', and assign it to internal array
        for (std::size_t i = 0; i < list.size(); ++i)
            arr[i] = *(list.begin() + i); //list.begin() returns an iterator to the firsts
                                          //element, which can be moved using +
                                          //(deferenced to get the value)
    }

    //Overloads operator[] for easy access (no bounds checking!)
    T operator[](std::size_t index)
    {
        return arr[index];
    }
private:
    T arr[size]; //internal array
};

然后您可以这样使用它:

array<int, 2> a = { 2, 5 };
int b = a[0]; //'b' == '2'