I'm trying to use variadic template to refactor some of my code, but the compiler has "no matching function for call" error. Below is a simplified version (it may not make sense for functionality, but an example to reproduce the error):
// base case
void testFunc(int i) { std::cout << i << std::endl; }
template <class T, class... Args> void testFunc(int i) {
T t = 0;
std::cout << t << std::endl;
testFunc<Args...>(i);
}
int main() {
testFunc<int, long, float>(1);
return 0;
}
The error messages:
main.cpp:9:3: error: no matching function for call to 'testFunc'
testFunc<Args...>(i);
^~~~~~~~~~~~~~~~~
main.cpp:9:3: note: in instantiation of function template specialization 'testFunc<float>' requested here
main.cpp:9:3: note: in instantiation of function template specialization 'testFunc<long, float>' requested here
main.cpp:13:3: note: in instantiation of function template specialization 'testFunc<int, long, float>' requested here
testFunc<int, long, float>(1);
^
main.cpp:6:40: note: candidate template ignored: couldn't infer template argument 'T'
template <class T, class... Args> void testFunc(int i) {
^
1 error generated.
It looks like that the unwrapping of template parameters is working, and stops at the base case. But I have defined the base case. Why there is no matching function?
The problem is that calling
testFunc<Args...>(i);
you call the template version of testFunc()
, not the base case version.
And when Args...
is empty, there isn't a template version available.
To solve this problem... if you can use C++17, you can use if constexpr
, as suggested by YSC.
For C++11 and C++14, I propose to use the template partial specialization of a struct
.
The following is a full working example
#include <iostream>
// base case
template <typename...>
struct foo
{ static void bar (int i) { std::cout << i << std::endl; } };
// recursive case
template <typename T, typename ... Args>
struct foo<T, Args...>
{
static void bar (int i)
{
std::cout << T{} << std::endl;
foo<Args...>::bar(i);
}
};
int main()
{
foo<int, long, float>::bar(1);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With