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 :/

6
  • 2
    Do you really need to initialize all the elements to a specific value? std::array<std::array<int,3>,3> x{} will make them all 0's if you are okay with that. Commented May 22, 2018 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. Commented May 22, 2018 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. Commented May 22, 2018 at 16:36
  • What kind of values are you dealing with? Commented May 22, 2018 at 16:45
  • @Holt The inner arrays consist on numerical values (be them int, bool, double,...). No tricks here ;) Commented May 22, 2018 at 16:56

1 Answer 1

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))} {}
};
Sign up to request clarification or add additional context in comments.

3 Comments

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 :)
index_sequence might be implemented in C++11 too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.