Boiethios
Boiethios

Reputation: 42769

Sequence array initialization with template

I want to initialize an array with a sequence of ints from 0 to N - 1

#include <array>
#include <iostream>

template<unsigned N>
struct XArray
{
    static constexpr int array[N] = {XArray<N - 1>::array, N - 1};
};

template<>
struct XArray<1>
{
    static constexpr int array[1] = {0};
};


int main(void)
{
    std::array<int, 10> const   a{XArray<10>::array};

    for (int const & i : a)
        std::cout << i << "\n";
    return 0;
}

I tried that, but it does not work, since XArray<N - 1>::array in my struct must be int, and not int *. How can I do this ? How to "concatenate" the values ?

Upvotes: 5

Views: 1277

Answers (2)

user12002570
user12002570

Reputation: 1

You can create a make_array function template that will return the required std::array with elements from 0 to N-1 as shown below:

C++17 Version

template<std::size_t N> std::array<int, N> constexpr make_array()
{
    std::array<int, N> tempArray{};
    int count = 0;
    for(int &elem:tempArray)
    {
        elem = count++;
    }
    return tempArray;
}
int main()
{
    
    //-------------------------------vv------>pass the size here 
    constexpr auto arr  = make_array<10>();
   

    
    //lets confirm if all objects have the expected value 
    for(const auto &elem: arr)
    {
        std::cout << elem << std::endl; //prints 1 2 3 4 5 6 7 8 with newline in between
    }
    
}

Working demo C++17

The output of the above program is :

0
1
2
3
4
5
6
7
8
9

C++11 Version

Here the constexpr has been removed since std::array::begin is not constexpr in C++11.

template<std::size_t N> std::array<int, N> make_array()
{
    std::array<int, N> tempArray{};
    int count = 0;
    for(int &elem:tempArray)
    {
        elem = count++;
    }
    return tempArray;
}
int main()
{
    
    //---------------------vv------>pass the size here 
    auto arr  = make_array<10>();
   

    
    //lets confirm if all objects have the expected value 
    for(const auto &elem: arr)
    {
        std::cout << elem << std::endl; //prints 1 2 3 4 5 6 7 8 with newline in between
    }
    
}

Working demo C++11

Upvotes: 0

AlphaRL
AlphaRL

Reputation: 1629

I'm not sure if this meets your requirements.

#include <array>
#include <iostream>

template <size_t ...I>
constexpr auto init(std::index_sequence<I...>) {
    return std::array<size_t, sizeof...(I)>{I...};
}

int main(void)
{
    std::array<size_t, 10> a = init(std::make_index_sequence<10>());

    for (int const & i : a)
        std::cout << i << "\n";
    return 0;
}

Upvotes: 8

Related Questions