I have difficulties to understand the following. Why does this code compile
template <size_t N, size_t... N_i, size_t... M_i>
auto foo2(std::index_sequence<M_i...> = std::make_index_sequence<N>())
{
constexpr size_t values[] = {N_i...};
return A<values[M_i]...>();
}
template <size_t N,size_t... N_i>
auto foo()
{
return foo2<N,N_i...>(std::make_index_sequence<N>());
}
int main()
{
foo<2, 1,2,3>();
}
but this not (where I use the default argument of foo2
):
template <size_t N, size_t... N_i, size_t... M_i>
auto foo2(std::index_sequence<M_i...> = std::make_index_sequence<N>())
{
constexpr size_t values[] = {N_i...};
return A<values[M_i]...>();
}
template <size_t N,size_t... N_i>
auto foo()
{
return foo2<N,N_i...>();
}
int main()
{
foo<2, 1,2,3>();
}
Many thanks in advance.
Given:
template <size_t N, size_t... N_i, size_t... M_i>
auto foo2(std::index_sequence<M_i...> = std::make_index_sequence<N>());
You can't explicitly specify M_i
(because the sequence would just get swallowed up as part of N_i
). If you specify an argument, then the compiler can use template argument deduction to work out what M_i
is. If you don't specify an argument, then the compiler has no way to deduce what M_i
is (and it needs to know that before it can start deciding you need a default argument, and what that argument is).
Assuming that this is a smaller part of a larger whole, then the fix is to write
template <size_t N, size_t... N_i, size_t... M_i>
auto foo2(std::index_sequence<M_i...>)
{
constexpr size_t values[] = {N_i...};
return A<values[M_i]...>();
}
template <size_t N,size_t... N_i>
auto foo2()
{
return foo2<N,N_i...>(std::make_index_sequence<N>());
}
Then you can indeed write:
template <size_t N,size_t... N_i>
auto foo()
{
return foo2<N,N_i...>();
}