У меня есть несколько классов (Foo
и Bar
здесь для простоты)
struct Bar {};
struct Foo {};
и функция, которая принимает один параметр шаблона и делает что-то на основе этого типа:
template <typename T>
constexpr void doSomething() { cout << "Am I a Foo? " << is_same<T,Foo>::value << endl; }
В моем коде мне дан пакет параметров шаблона Foo
с и Bar
с, и я должен вызывать функцию doSomething()
для каждого из них (меня не волнует порядокв котором выполняются функции).
doStuff<Foo, Bar, Bar>(); // --> True / False / False
Пока что единственное решение, которое я мог придумать, это:
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
Это работает, но я нахожу это довольно грязным.Мне пришлось использовать шаблон класса с частичной специализацией, потому что шаблоны функций поддерживают только полную специализацию.Я также пытался
constexpr void doStuff() { }
template <typename Head, typename... Tail>
constexpr void doStuff() {
doSomething<Head>();
doStuff<Tail...>(); // --> Compile Error
}
, но компилятор не работает, потому что он не может понять, что doStuff<>()
на самом деле doStuff()
.Если у меня есть аргументы в моих функциях variadic, то компилятор достаточно умен, чтобы разрешить этот конфликт, поскольку он применяет вывод типа шаблона:
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
Я что-то упустил?Есть ли способ заставить мою функцию с переменным значением работать без использования параметров функции или шаблонов классов?