Victor Calixtro
Victor Calixtro

Reputation: 5

Variadic template not compiling

#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

Answers (2)

Joe
Joe

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

max66
max66

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

Related Questions