引数の数が未知の関数に、自動で引数を付けて呼び出す。

```cpp
#include <iostream>

int func3(int n1, int n2, int n3) {
    std::cout << n1 << '+' << n2 << '+' << n3 << '=' << std::flush;
    return n1+n2+n3;
}
int func2(int n1, int n2) {
    std::cout << n1 << '+' << n2 << '=' << std::flush;
    return n1+n2;
}
int func1(int n1) {
    std::cout << n1 << '=' << std::flush;
    return n1;
}
int func0(void) {
    return 0;
}

int main(void){
    std::cout << func3(1,2,3) << std::endl;
    std::cout << func2(1,2) << std::endl;
    std::cout << func1(1) << std::endl;
    std::cout << func0() << std::endl;
    return 0;
}
```

実行すると、

```text
1+2+3=6
1+2=3
1=1
0
```

こんな感じ。

この`main()`関数の部分が、書くのが面倒くさいので、

```cpp
int main(void){
    std::cout << stepargs(func3) << std::endl;
    std::cout << stepargs(func2) << std::endl;
    std::cout << stepargs(func1) << std::endl;
    std::cout << stepargs(func0) << std::endl;
    return 0;
}
```

とだけ書いたら、自動的に連番整数を引数として関数を実行してほしい、というのがお題。

```cpp
#include <type_traits>

template<int N, typename Func, typename ...Args>
auto add_steparg(typename std::enable_if<!N, Func>::type func, Args... args) {
    return func(args...);
}

template<int N, typename Func, typename ...Args>
auto add_steparg(typename std::enable_if<N, Func>::type func, Args... args) {
    return add_steparg<N-1, Func>(func, N, args...);
}

template<typename Ret, typename ...Args>
Ret stepargs(Ret (*func)(Args...)) {
    return add_steparg<sizeof...(Args), decltype(func)>(func);
}
```

これを`main()`関数の前に書いてやればOK。

ここでは関数呼び出しのために、再帰でテンプレート引数を伸ばしていっている。
伸ばす長さの目印として、`template<int N>`に`sizeof...(Args)`を最初に渡しておいて、再帰の度に減らして、ゼロになったら目的の関数を呼び出す。

しかし可変長テンプレート＋可変長引数と`std::enable_if`との相性悪い・・・。
テンプレート引数や、関数引数の最後に、`std::enable_if`を使ったデフォルト値付きのダミーの引数を付けられないので、無理矢理どこかに押し込まないといけない。

```cpp
#include <type_traits>

template<int N, typename Func, typename ...Args>
auto add_steparg(typename std::enable_if<!N>::type*, Func func, Args... args) {
    return func(args...);
}

template<int N, typename Func, typename ...Args>
auto add_steparg(typename std::enable_if<N>::type*, Func func, Args... args) {
    return add_steparg<N-1>(0, func, N, args...);
}

template<typename Ret, typename ...Args>
Ret stepargs(Ret (*func)(Args...)) {
    return add_steparg<sizeof...(Args)>(0, func);
}
```

関数引数の最初にデフォルト値なしのダミー引数を付けた方がシンプルかな。
当然呼び出し元にもダミーの引数を付けないといけないけれど。
その代わりに、テンプレート引数に`Func`を付けなくても推論してくれるようになった。

```cpp
template<int N> struct add_steparg{
    template<typename Func, typename ...Args>
    static auto x(Func func, Args... args) {
        return add_steparg<N-1>::x(func, N, args...);
    }
};

template<> struct add_steparg<0>{
    template<typename Func, typename ...Args>
    static auto x(Func func, Args... args) {
        return func(args...);
    }
};

template<typename Ret, typename ...Args>
Ret stepargs(Ret (*func)(Args...)) {
    return add_steparg<sizeof...(Args)>::x(func);
}
```

`std::enable_if`を使わずに、テンプレート特殊化でやった場合。`struct`がちょっと鬱陶しい。

ちなみに最適化MAXでコンパイルすると、単なる定数引数での関数呼び出しと同じになりました。なので実行時のオーバヘッドはゼロ。GCCすごい。

追記
-----
`if constexpr`が使えるなら、下記でも大丈夫の模様。

```cpp
template<int N, typename Ret, typename Func, typename ...Args>
Ret add_steparg(Func func, Args... args) {
    if constexpr(N) {
        return add_steparg<N-1, Ret>(func, N, args...);
    } else {
        return func(args...);
    }
}

template<typename Ret, typename ...Args>
Ret stepargs(Ret (*func)(Args...)) {
    return add_steparg<sizeof...(Args), Ret>(func);
}
```