11

How can I at compile time create for example an std::array from a template parameter pack?

This shows what I need, but without a parameter pack.

template<typename T1, typename T2, typename T3>
struct ToInfoArray
{
    static constexpr std::array<Info, 3> value = { { T1::info, T2::info, T3::info } };
};

Live demo demonstrating the intended usage

Bonus question: Would you use std::array, array[] or std::initializer_list as type for InfoArray?

Mathias
  • 1,446
  • 2
  • 16
  • 31

2 Answers2

10
template <typename... Ts>
struct ToInfoArray
{
    static constexpr std::array<Info, sizeof...(Ts)> value = { { Ts::info... } };
};

DEMO

Would you use std::array, array[] or std::initializer_list as type for InfoArray?

std::array<T,N>. It's an aggregate that behaves (with comparable performance) just like a regular array, but provides an additional interface for operating on its elements; itself, it's a copyable type.

std::initializer_list is not an option here for numerous reasons. Once it's used as a data member (with an in-class initializer), the elements it stores are invalidated after any of constructors' execution. It's not guaranteed to be a literal type, thus it can't be marked as constexpr. Its size is not usable (accessible) in constant expressions. It doesn't provide random access logic (without resorting to pointer arithmetic); the only way to enumerate its elements is to iterate from begin() to end(), which in addition yields pointers to constant items. std::initializer_list was designed to serve primarily as a function parameter.

Piotr Skotnicki
  • 46,953
  • 7
  • 118
  • 160
3

With C++14, you can simply make it a variable template:

template <typename... Ts>
constexpr std::array<Info, sizeof...(Ts)> value{{Ts::info...}};

Otherwise, the correct syntax for your usage is:

template <typename... Ts>
struct ToInfoArray
{
    static constexpr std::array<Info, sizeof...(Ts)> value{{Ts::info...}};
};

And strongly prefer std::array<> to raw arrays or an initializer_list.

Barry
  • 286,269
  • 29
  • 621
  • 977