Reputation: 1
i want to use recursive variadic templates with a base case with more than 2 types. The following example does not compile. What could be the problem?
My expectation was that f<int, int>(5) would call a case like:
[with T = int; Arg = int; Args = {int}]
but that seems to be no option for the compiler (g++ c++17) ;)
template<class T, typename Arg, typename... Args>
void f(T a) {
}
template<class T, typename Arg>
void f (T a) {
}
int main() {
f<int, int>(5);
return 0;
}
<source>: In function 'int main()':
<source>:11:18: error: call of overloaded 'f<int, int>(int)' is ambiguous
11 | f<int, int>(5);
| ^
<source>:2:6: note: candidate: 'void f(T) [with T = int; Arg = int; Args = {}]'
2 | void f(T a) {
| ^
<source>:6:6: note: candidate: 'void f(T) [with T = int; Arg = int]'
6 | void f (T a) {
| ^
Compiler returned: 1
Upvotes: 0
Views: 56
Reputation: 117433
You can combine both cases and use a constexpr if statement in the function template:
#include <iostream>
template<class T, typename Arg, typename... Args>
void f(T a) {
std::cout << sizeof...(Args) << '\n';
if constexpr (sizeof...(Args) > 0) {
f<T, Args...>(a);
}
}
int main() {
f<int, int>(5);
std::cout << "---\n";
f<int, int, double, float, int>(5);
}
Output:
0
---
3
2
1
0
Upvotes: 1