0

I want to initialize my array items while avoiding unnecessary instances and copies (similar to this question: initialize std::array without copying/moving elements).

An initializer list does work for a small amount of objects.

Bit I want to do this via a code snippet since my array has several hundreds of items...

How can I do this?

#include <array>
#include <iostream>

class mytype {
public:
    int a;
    mytype() : a(0) {}
    mytype(int a) : a(a) {}
};

int main() {
    // explict constructor calls to instantiate objects does work
    std::array<mytype, 2> a = { { mytype(10), mytype(20) } };
    std::cout << a[0].a;  // 10

    // I want to do something like this - what does not work of course
    std::array<mytype, 2> b = { { for (i = 0, i++, i < 2) mtype(10 * i); } };
}
Piotr Skotnicki
  • 46,953
  • 7
  • 118
  • 160
R Yoda
  • 8,358
  • 2
  • 50
  • 87

2 Answers2

1

This is typically accomplished with a pair of templates:

namespace detail {
    template<std::size_t... Idx>
    auto make_mytype_array(std::index_sequence<Idx...>) {
        return std::array<mytype, sizeof...(Idx)>{{
            mytype(10 * Idx)...
        }};
    }
}

template<std::size_t N>
auto make_mytype_array() {
    return detail::make_mytype_array(make_index_sequence<N>{});
}

The above are a pair of utility free functions, but can be folded into the class if need be. If you need it for more than just an expression like 10*i, then a lambda can be passed as another argument (templated to be a general "callable"). With copy elision this will all collapse into direct initialization of the result array object.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
1

In :

#include <array>
#include <utility>
#include <cstddef>

template <typename T, std::size_t... Is>
std::array<T, sizeof...(Is)> to_array(std::index_sequence<Is...>)
{
    return { T(Is*10)... };
}

template <typename T, std::size_t N>
std::array<T, N> to_array()
{
    return to_array<T>(std::make_index_sequence<N>{});
}

int main() 
{
    std::array<mytype, 10> b(to_array<mytype, 10>());
}

DEMO

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