I have multiple classes (Foo
and Bar
here for simplicity)
struct Bar {};
struct Foo {};
and a function that takes a single template parameter and does something based on that type:
template <typename T>
constexpr void doSomething() { cout << "Am I a Foo? " << is_same<T,Foo>::value << endl; }
In my code, I am given a template parameter pack of Foo
s and Bar
s, and I am supposed to call the doSomething()
function on each one of them (I do not care about the order in which the functions are executed).
doStuff<Foo, Bar, Bar>(); // --> True / False / False
So far, the only solution I could come up with is this:
template <typename... Ts>
class Doer;
template <>
struct Doer <> {
static constexpr void doStuff() {}
};
template <typename Head, typename... Tail>
struct Doer <Head, Tail...> {
static constexpr void doStuff() {
doSomething<Head>();
Doer<Tail...>::doStuff();
}
};
template <typename... Ts>
constexpr void doStuff() {
return Doer<Ts...>::doStuff();
}
doStuff<Foo, Bar, Bar>(); // --> True / False / False
It works, but I find it rather messy. I had to use a class template with partial specializations because function templates only support full specialization. I also tried
constexpr void doStuff() { }
template <typename Head, typename... Tail>
constexpr void doStuff() {
doSomething<Head>();
doStuff<Tail...>(); // --> Compile Error
}
but the compiler fails because it can't figure out that doStuff<>()
is actually doStuff()
. If I have arguments in my variadic functions, then the compiler is smart enough to resolve this conflict as it applies template type deduction:
constexpr void doStuff() { }
template <typename Head, typename... Tail>
constexpr void doStuff(Head arg, Tail... args) {
doSomething<Head>();
doStuff(args...);
}
Foo f1;
Bar b1, b2;
doStuff<Foo, Bar, Bar>(f1, b1, b2); // --> True / False / False
Am I missing something? Is there a way to get my variadic function working without using function parameters or class templates?