Search code examples
c++c++17variadic-templatestemplate-meta-programmingtemplate-argument-deduction

Deduce parameter pack from default argument


Is it possible for the compiler to deduce a parameter pack from a function's default aargument? Particularly, I have the following code:


template <int ... Is> struct seq {};
template <int ... Is> struct make_seq;
template <int head, int ... tail>
struct make_seq<head, tail...>
{
    using type = typename make_seq<head - 1, head - 1, tail...>::type;
};
template <int ... Is>
struct make_seq<0, Is...>
{
    using type = seq<Is...>;
};
template <int N>
using make_seq_t = typename make_seq<N>::type;

template<int N, int ...Is>
int deduceParamPack(seq<Is...> s = make_seq_t<N>{})
{
    return sizeof...(Is);
}

int main()
{
    return deduceParamPack<5>();
}

And the compiler deduces the parameter pack as empty, and tries to cast the default argument to it. Instead, I would like to achieve a similar behaviour to:

int main()
{
    return deduceParamPack<5>(make_seq_t<5>{});
}

where the deduced parameter pack is 0,1,2,3,4, without explicitly passing in this argument.


Solution

  • Is it possible for the compiler to deduce a parameter pack from a function's default aargument?

    No, as far I know.

    But... not exactly what you asked... but maybe you can find useful the following solution based in partial specialization of structs

    template <std::size_t N, typename = std::make_index_sequence<N*N>>
    struct deduceParamPackStruct;
    
    template <std::size_t N, std::size_t ... Is>
    struct deduceParamPackStruct<N, std::index_sequence<Is...>>
     {
       static constexpr std::size_t func ()
        { return sizeof...(Is); }
     };
    

    You can use it as follows

    static_assert( 25 == deduceParamPackStruct<5>::func() );