Home > Software design >  Parameter pack iteration
Parameter pack iteration

Time:05-14

Why this code doesn't compile ?

#include <iostream>
#include <typeinfo>

template <typename ...Ts>
void f();

template <typename T>
void f() {
    std::cout << typeid(T).name() << std::endl;
}

template <typename T, typename U, typename ...Ts>
void f() {
    std::cout << typeid(T).name() << ", ";
    f<U, Ts...>();
}

int main(int argc, char** argv)
{
    f<int, float, char>();
}

MSVC compiler error: error C2668: 'f': ambiguous call to overloaded function

Expected output:

int, float, char

Side question: would there be a more modern way to do the same thing ?

CodePudding user response:

Compiling with g gives a pretty clear explanation of what's happening:

prog.cc: In function 'int main(int, char**)':
prog.cc:20:24: error: call of overloaded 'f<int, float, char>()' is ambiguous
   20 |     f<int, float, char>();
      |     ~~~~~~~~~~~~~~~~~~~^~
prog.cc:5:6: note: candidate: 'void f() [with Ts = {int, float, char}]'
    5 | void f();
      |      ^
prog.cc:13:6: note: candidate: 'void f() [with T = int; U = float; Ts = {char}]'
   13 | void f() {

You've provided three different templated functions f, two of which could match what you've written here.

EDIT: Maybe you thought the first one was a declaration and the other two are specializations, but that's not how templates work. Specialization means specializing the type or value of a particular template argument, not specializing the number of template arguments.

Deleting

template <typename ...Ts>
void f();

will make the program compile and run with the expected behavior.

  • Related