Reputation: 5
#include <iostream>
template<typename A, typename... B>
void prints(A num, B... args){
std::cout << num << std::endl;
prints(args...);
}
int main(){
prints(1,2,3);
return 0;
}
When I compile, I get these errors:
In instantiation of 'void prints(A, B ...) [with A = int; B = {}]': error: no matching function for call to 'prints()' main.cpp:4:10: note: template argument deduction/substitution failed: main.cpp:7:11: note: candidate expects at least 1 argument, 0 provided
Upvotes: 1
Views: 534
Reputation: 171
Another solution using fold expressions is shown below:
#include <iostream>
#include <utility>
template <class... TArgs>
void prints(TArgs&&... args) {
(std::cout << ... << std::forward<TArgs>(args));
}
int main(){
prints(1,2,3);
return 0;
}
Upvotes: 1
Reputation: 66230
Your function waits for 1 or more parameters:
template<typename A, typename... B>
void prints(A num, B... args)
When you invoke it with only 1 parameter, the args...
pack is empty, so the recursive call:
prints(args...);
becomes
prints();
But your function waits for (at least) 1 argument, so can't match this call.
You need to add a zero-argument overload of prints()
to match the empty call:
void prints()
{ }
and you have to declare it before the recursive version.
As pointed by Evg (thanks) starting from C++17 you can avoid the zero-argument overload and, using if constexpr
, you can call the recursion only when args...
isn't empty.
That is... starting from C++17 you can write
template <typename A, typename... B>
void prints (A num, B... args) {
std::cout << num << std::endl;
if constexpr ( sizeof...(args) > 0u )
prints(args...);
}
and you don't need the zero-argument overload anymore.
Observe that if you simply write (with a simple if
, no if constexpr
)
if ( sizeof...(args) > 0u )
prints(args...);
you get (without the zero-argument overload) a compilation error because the compiler has to compile the prints(args...)
part also when sizeof...(args)
is zero (it's exactly if constexpr
that avoid this).
Upvotes: 5