call template function for each template parameter in constexpr std::array<size_t,3>

Given a function print<size_t>(void) and a constexpr std::array<size_t,3> q={1,2,3}, I want a loop that calls print<qi> for each qi in q.

My minimal example looks like this:

#include<iostream>
#include<array>

template<size_t n>
void print(){ std::cout << n << "\n"; }

template< size_t N, const std::array<const size_t,N> q>
constexpr void print_long(){
    //
    // I) this is what I want to do
    for(size_t i=0;i<N;++i){ print<q[i]>(); }
    //
    // II) this does not compile either (because "it++")
    constexpr auto it = q.begin();
    while(it!=q.end()){ print<*(it++)>(); }
    //
    // III) for_each is no constexpr either
    std::for_each(q.begin(),q.end(),[](const auto& it){ print<it>(); });
}

int main(){
    constexpr size_t N=3;
    constexpr std::array<const size_t,N> q={1,2,3};
    //
    print_long<N,q>();
}

I seek a clean, practical, concise, readable, maintainable, code solution.

I tried the variants in I, II, III. I was hoping that at least III might work, or that there is a practical framework in the std for running compile-time for loops over constexpr arrays.

>Solution :

In C++20 you can:

template< size_t N, const std::array<const size_t,N> q>
constexpr void print_long() {
    []<std::size_t... Is>(std::index_sequence<Is...>) {
        (print<q[Is]>(), ...);
    }(std::make_index_sequence<N>{});
}

Demo

Leave a Reply