4

I have and std::array of std::array, and say that I want to initialize all the arrays to {1,2,3}. We write:

std::array<std::array<int,3>,3> x{{1,2,3},{1,2,3},{1,2,3}};

This is not very handy. It becomes really messy when you have more than 3 arrays, or each array has more than 3 elements.

However, it becomes even worse if the size of the array is not known a priori:

template <size_t n, size_t T> struct foo{
  std::array<std::array<int,n>,T> x;
}

How can you initialize x? To make it clearer, I would like to initialize all the arrays in x to an array of a certain parameter that is given. That is, something like:

template <size_t n, size_t T> struct foo{
  static constexpr int N{20};

  std::array<std::array<int,n>,T> x;

  foo() : x{ {N,N,...}, {N,N,...}, ...} {}
}

(If that were possible). Any suggestion or ideas? I can always iterate through x and call the method fill, as in the following piece of code:

for (size_t idx = 0; idx < x[0].size(); idx++)
  x[idx].fill(N);

But that is not initialization, right? I am new to using std::array and I do not know whether I am asking something dummy here :/

enanone
  • 923
  • 11
  • 25
  • 2
    Do you really need to initialize all the elements to a specific value? `std::array,3> x{}` will make them all `0`'s if you are okay with that. – NathanOliver May 22 '18 at 16:33
  • 1
    Does `foo` know what it should initialize the elements to? Should this be delegated to the caller? You're sort-of implying you know what the values should be, but don't actually say. – Useless May 22 '18 at 16:34
  • @NathanOliver, @Useless you are both correct. I know that all the elements should be initialized to some value other than `0`. I will change the question. – enanone May 22 '18 at 16:36
  • What kind of values are you dealing with? – Holt May 22 '18 at 16:45
  • @Holt The inner arrays consist on numerical values (be them `int`, `bool`, `double`,...). No tricks here ;) – enanone May 22 '18 at 16:56
  • If you really write `std::array,3> x{{1,2,3},{1,2,3},{1,2,3}};` you get a compilation error. You should add an extra pair of braces around the construct. (Why?) – andreipb Nov 30 '20 at 10:06

1 Answers1

1

With std::index_sequence, you might do something like:

template <std::size_t ... Is, typename T>
constexpr std::array<T, sizeof...(Is)>
make_array(const T& value, std::index_sequence<Is...>)
{
    return {{(void(Is), value)...}};
}

template <std::size_t N, typename T>
constexpr std::array<T, N> make_array(const T& value)
{
    return make_array(value, std::make_index_sequence<N>());
}

and then:

template <size_t n, size_t T>
struct foo{
    static constexpr int N{20};

    std::array<std::array<int,n>,T> x;

    foo() : x{make_array<T>(make_array<n>(N))} {}
};
Passer By
  • 19,325
  • 6
  • 49
  • 96
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • I just tested it, it is insane (insanly good, I mean). Only issue here is that I need C++14 to make it work. Is there a way of fitting your solution to C++11? I am very thankful for your answer, though :) – enanone May 22 '18 at 16:58
  • `index_sequence` might be implemented in C++11 too. – Jarod42 May 22 '18 at 17:00
  • For example: [implementation-c14-make-integer-sequence](https://stackoverflow.com/questions/17424477/implementation-c14-make-integer-sequence) – Jarod42 May 22 '18 at 17:17