Home > Software design >  How to specify a default argument for a template parameter pack?
How to specify a default argument for a template parameter pack?

Time:05-27

I have the following method

template <std::size_t N, std::size_t... Indices>
void doSomething()
{
    ...
};

It seems not possible to supply default values for Indices, e.g.

template <std::size_t N, std::size_t... Indices = std::make_index_sequence<N>>
void doSomething()
{
    ...
};

Compiler complains that

error: expected primary-expression before '>' token
template <std::size_t N, std::size_t... Indices = std::make_index_sequence<N>>
                                                                             ^~
error: template parameter pack 'Indices' cannot have a default argument
template <std::size_t N, std::size_t... Indices = std::make_index_sequence<N>>
                                    ^~~

Is there any way around this?

CodePudding user response:

This is impossible. However, you can wrap parameter pack with index_sequence and expand them in the function body

#include <cstddef>
#include <utility>

template <std::size_t N, class Indices = std::make_index_sequence<N>>
void doSomething() {
  []<std::size_t... Is>(std::index_sequence<Is...>) {
    // expand parameter pack
  }(Indices{});
};

Demo

CodePudding user response:

There's already two excellent answers so far (including NathanOliver's comment). I think that having a couple of overloads that act as wrappers is really the simplest solution here, but just for completeness, let's provide your desired functionality in one function:

Often it's best to take as much of the template logic out of the parameter list as possible (separating inputs from logic):

template <std::size_t N, std::size_t... Indices>
void doSomething()
{
    using Ints
        = std::conditional_t<
            /* if */ (sizeof...(Indices) > 0),
                std::index_sequence<Indices...>,
            /* else */
                std::make_index_sequence<N>>;

    // ...
};

demo

  • Related