'Parameter pack iteration
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 ?
EDIT I've found a way to accept zero template pack:
#include <typeinfo>
#include <iostream>
#include <type_traits>
template <typename ...Ts>
using is_empty_pack = std::enable_if_t<sizeof ...(Ts) == 0>;
template <typename ...Ts, typename = is_empty_pack<Ts...>>
void f() {}
template <typename T, typename ...Ts>
void f() {
std::cout << typeid(T).name();
if constexpr (sizeof ...(Ts) > 0) std::cout << ", "; else std::cout << std::endl;
f<Ts...>();
}
int main(int argc, char *argv[])
{
f<>();
f<int>();
f<int, float>();
}
Any other suggestion?
Solution 1:[1]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Daniel McLaury |