Straightforward using of default parameter value to generate integer sequence as follows lead to hard error (complier clang-3.6):
#include <iostream>
#include <utility>
#include <cstdlib>
template< std::size_t M, std::size_t N > // say M - arity, N - number of types
struct test
{
template< std::size_t ...i >
void
operator () (std::index_sequence< i... > = std::make_index_sequence< M >{}) const
{
std::size_t indices[M];
for (std::size_t & m : indices) {
m = 0;
}
for (;;) {
(std::cout << ... << indices[i]) << std::endl;
std::size_t m = 0;
for (;;) {
std::size_t & n = indices[m];
++n;
if (n != N) {
break;
}
n = 0;
if (++m == M) {
return;
}
}
}
}
};
int
main()
{
#if 0
test< 3, 3 >{}(); // hard error
#else
test< 3, 3 >{}(std::make_index_sequence< 3 >{}); // ugly workaround
#endif
return EXIT_SUCCESS;
}
It looks strange, because simple substitution works as intended.
Why is it so? Why default parameter cannot be assigned in above a case, but explicit assignment works?
Appending const &
or &&
to parameter type does nothing.
Template arguments can't be deduced from default arguments. This is why we typically delegate to a helper function before building the sequence: