1

I try to create an std::initializer_list of bind values, compile time using the following function.

However, I can't get it correctly.

template<class T, int N> auto b(T t) -> auto
{
    if constexpr (N == 0) {
        return std::initializer_list<????????>{ std::bind(t, 0) };
    }
    else {
        return std::initializer_list { b<decltype(t), N-1>(t), std::bind(t, 0) };
    }
}

All this is to avoid code like:


char F(int c) { return 42; /* do something with c or course */ }
// ....
auto fs = { std::bind(F, 0), 
    std::bind(F, 1), 
    std::bind(F, 2), 
    std::bind(F, 3),
    std::bind(F, 4), 
    std::bind(F, 5) /*, etc ...*/};

Is there anyone who can guide me towards a feasible solution?

JeJo
  • 30,635
  • 6
  • 49
  • 88
Ferenc Deak
  • 34,348
  • 17
  • 99
  • 167
  • The problem is that each recursive call returns an initializer_list. Which gets placed into another initializer_list. Hillarity ensues. This should be doable with a simple fold expression. Declare `template> auto b(T t) -> auto`, then specialize it for a variadic template, and generate a fold expression, that should work, I think. – Sam Varshavchik Feb 27 '23 at 13:54

1 Answers1

3

I would recommend having a std::array of binded objects, instead of std::initializer_list of binded objects.

Something along the lines

namespace impli {
    template<typename T, std::size_t ...I>
    auto make_binded_funcs(T&& t, std::index_sequence<I...>)
    {
        return std::array{std::bind(t, I)...};
    }
}

template<std::size_t N, typename T> auto b(T&& t) 
{
    return impli::make_binded_funcs(
                            std::forward<T>(t), std::make_index_sequence<N>{});
}

and you would call it like:

auto fs{ b<5>(&F) };

See a demo here


In C++20, using template lambda this can be however in one function.

template<std::size_t N, class T>
auto b(T t)
{
    return[t]<std::size_t ...I>(std::index_sequence<I...>) {
        return std::array{std::bind(t, I)...};
    }(std::make_index_sequence<N>{});
}

See a demo here

JeJo
  • 30,635
  • 6
  • 49
  • 88