The following C++20 program:
#include <utility>
#include <cstddef>
template<typename... Args>
class C {
template<size_t... I>
static void call(
std::index_sequence<I...> = std::index_sequence_for<Args...>{}
) {}
};
int main() {
C<long int>::call();
}
fails to compile with error message:
test.cc: In static member function ‘static void C<Args>::call(std::index_sequence<I ...>) [with long unsigned int ...I = {}; Args = {long int}; std::index_sequence<I ...> = std::integer_sequence<long unsigned int>]’:
test.cc:11:20: error: could not convert ‘std::index_sequence_for<long int>{}’ from ‘integer_sequence<[...],#‘nontype_argument_pack’ not supported by dump_expr#<expression error>>’ to ‘integer_sequence<[...],#‘nontype_argument_pack’ not supported by dump_expr#<expression error>>’
11 | C<long int>::call();
| ^
| |
| integer_sequence<[...],#‘nontype_argument_pack’ not supported by dump_expr#<expression error>>
test.cc:11:20: note: when instantiating default argument for call to ‘static void C<Args>::call(std::index_sequence<I ...>) [with long unsigned int ...I = {}; Args = {long int}; std::index_sequence<I ...> = std::integer_sequence<long unsigned int>]’
test.cc: In function ‘int main()’:
test.cc:11:20: error: could not convert ‘std::index_sequence_for<long int>{}’ from ‘integer_sequence<[...],#‘nontype_argument_pack’ not supported by dump_expr#<expression error>>’ to ‘integer_sequence<[...],#‘nontype_argument_pack’ not supported by dump_expr#<expression error>>’
Any ideas?
Update:
My current best workaround is to factor out default argument into two functions like:
template<typename... Args>
class C {
static void call() {
_call(std::index_sequence_for<Args...>{});
}
template<size_t... I>
static void _call(std::index_sequence<I...>) {}
};
This seems to work around compiler bug (if that's what it is).
Update 2:
The below program fails for the same reason the original one does:
template<typename T> void f(T x = 42) {}
int main() { f(); }
so it's a feature not a bug.