Search code examples
c++templatesc++14constexprstdarray

intializing a std::array of objects that don't have default constructor from another constexpr std::array


Is it possible to initialize an array of objects whose members are initialized from another constexpr array of trivial objects. For example I have the following

struct X
{
  X(int y): _x(y){}
  int _x;
};

struct Z
{
  static constexpr std::array<int, 4> arr = {1,6,0,4};
  

  // How does one implement make_array below that constructs
  // X[0] from arr[0], X[1] from arr[1], etc.
  // Is it even feasible in C++14/17?
  std::array<X, arr.size()> xArr = make_array(  );  

};

Solution

  • With std::index_sequence:

    template <typename T, typename U, std::size_t N, std::size_t ... Is>
    constexpr std::array<T, N> make_array(const std::array<U, N>& a, std::index_sequence<Is...>)
    {
        return {{T(a[Is])...}};
    }
    
    template <typename T, typename U, std::size_t N>
    constexpr std::array<T, N> make_array(const std::array<U, N>& a)
    {
        return make_array<T>(a, std::make_index_sequence<N>());
    }
    

    Usage:

    static constexpr std::array<int, 4> arr = {1,6,0,4};
      
    /*constexpr*/ std::array<X, arr.size()> xArr = make_array<X>(arr);  
    

    Demo