C++ 如何从std::initializer\u列表构建类似std::数组的数据结构

C++ 如何从std::initializer\u列表构建类似std::数组的数据结构,c++,c++11,initializer-list,stdarray,C++,C++11,Initializer List,Stdarray,我想实现一个具有编译时常量大小的数据结构(如std::array)。我希望能够像这样初始化此数据结构: MyStruct<3, int> example = {1, 2, 3}; MyStruct示例={1,2,3}; 使用构造函数(如:MyStruct(std::initializer\u list elements))可以很好地实现这一点,但是编译器不会为我的内部结构和元素强制执行相同的大小,即使它们在编译时都是已知的 我不能使用static\u assert,因为eleme

我想实现一个具有编译时常量大小的数据结构(如
std::array
)。我希望能够像这样初始化此数据结构:

MyStruct<3, int> example = {1, 2, 3};
MyStruct示例={1,2,3};
使用构造函数(如:
MyStruct(std::initializer\u list elements)
)可以很好地实现这一点,但是编译器不会为我的内部结构和
元素强制执行相同的大小,即使它们在编译时都是已知的

我不能使用
static\u assert
,因为
elements.size()
不是编译时常量


有没有办法在编译时强制执行与
MyStruct
中相同大小的
元素?

std::array
没有构造函数!它不使用
初始值设定项列表
,而是使用
统一初始化
。(与POD结构类似,实际上
std::array
是POD结构)

因此,
std::array
的实际功能与以下内容非常相似:

template<int size, typename T>
struct array {
   T data[size];
   // and some member function here;
   // Warning! No constructors !
};
模板
结构数组{
T数据[大小];
//这里有一些成员函数;
//警告!没有构造器!
};
以后你什么时候写信

std::array<3, int> arr = {1,2,3};
std::array arr={1,2,3};
相当于

std::array<3, int> arr = {{1,2,3}};
std::array arr={{1,2,3};
这只是POD初始化,{1,2,3}被分配给
数据


如果要在编译时强制执行相同大小的检查,可以使用
std::array
本身而不是
std::initializer\u list


如果将初始化从
{1,2,3}
更改为
std::array{1,2,3}
,并将构造函数参数从
std::initializer\u list
更改为
std::array
用户将被强制传递大小为
size
的数组,则可以尝试使用可变模板的构造函数:

template<std::size_t N, typename E>
struct MyStruct {
    int otherStuff;
    E values[N];

    template<typename ...TT>
    MyStruct(TT&&...t) : values{std::forward<TT>(t)...} {
        static_assert(N == sizeof...(t), "Size mismatch!");
        for (size_t i = 0; i < N; i++) std::cout << values[i] << ",";
        std::cout << std::endl;
    }
};

原因是,单大括号仅适用于std::array,因为大括号省略并不总是适用于。

MyStruct的编译时常量大小与std::array类似,而不是std::array。如果没有提供值,我需要构造函数用默认值初始化。但是
std::array arr={1,2}
会用默认值arr[2]初始化,尽管您自己没有提供。arr[2]将等于0,但。。。可能默认值不是0。考虑一种颜色,根据颜色表示,我想使用默认值255或1.f。谢谢你的回答。我现在不会接受它-我需要使用clasic syntanx来构建我的结构。像这样使用它是非常混乱的。非常好,谢谢。我已经试过了,但是如果我添加默认构造函数,会出现一个警告-使用
g++
clang++
指定了多个默认构造函数(VS2013预览),当我添加
MyStruct()=default时,不会收到警告。你可以使用一些
enable_,如果
的话,但是我现在想不出什么有效的方法。这还允许您只启用具有正确数量的参数的构造函数,而不是触发断言。看见
MyStruct<3, int> example = {1,2,3};
MyStruct<3, int> exampleFail = {1,2}; //error: static assertion failed: Size mismatch!
MyStruct<3, int> exampleList{1,2,3}; // works
std::array<int, 3> arr = {1,2,3};    // works, but warning with clang++
std::array<int, 3> arrList{1,2,3};   // works with g++, does not compile with clang++