std :: array派生的类聚合初始化

时间:2018-08-13 11:18:39

标签: c++ c++11 templates variadic-templates aggregate-initialization

我正在制作一个小型的辅助类,该类来自std::array。构造函数显然不继承,而是负责括号初始化的对象。例如:

template<typename T, size_t size>
struct foo : std::array<T,size>
{
     foo(int a, int b)
     : std::array<T,size>{a,b}
     {
          //nothing goes here since constructor is just a dummy that 
          //forwards all arguments to std::array constructor
     }
}

int main()
{
     foo<int,2> myobj = {1,2}; //brace initialization calls custom constructor with inner elements as arguments
}

参数的数量必须完全匹配,因此我倾向于在构造函数中使用类似可变参数函数的参数(因为我不仅每次都会在数组中使用2个元素)。使用此方法,如何将可变参数包转发到std::array构造函数?我对允许初始化到std::array构造函数的其他括号初始化方法持开放态度。

注意:std::initializer_list需要运行时初始化,而我正在寻找兼容编译时/ constexpr的方法。谢谢。

2 个答案:

答案 0 :(得分:5)

您可以使用完善转发的构造函数:

template<class... U>
foo(U&&... u)
    : std::array<T, size>{std::forward<U>(u)...}
{}

答案 1 :(得分:0)

我认为从标准容器中继承不是一个好主意。

反正...

您可以使用可变参数模板,完善的转发功能以及SFINAE来强加参数数目恰好为size

您还可以将constexpr用作foo构造函数,以便可以制作constexpr foo对象。

通过示例

#include <array>
#include <type_traits>

template <typename T, std::size_t S>
struct foo : public std::array<T, S>
 {
   template <typename ... As,
             typename std::enable_if<sizeof...(As) == S>::type * = nullptr>
   constexpr foo (As && ... as)
      : std::array<T, S>{ { std::forward<As>(as)... } }
    { }
 };

int main ()
 {
   //constexpr foo<int, 2u> myobj1 = {1}; // compilation error
   constexpr foo<int, 2u> myobj2 = {1, 2}; // compile
   //constexpr foo<int, 2u> myobj3 = {1, 2, 3}; // compilation error
 }