Как проверить тип параметра шаблона?
Предположим, что у меня есть функция шаблона и два класса
class animal {
}
class person {
}
template<class T>
void foo() {
if (T is animal) {
kill();
}
}
Как сделать проверку для T - это животное? Я не хочу иметь
то, что проверяется во время выполнения. Благодаря
Ответы
Ответ 1
Используйте is_same
:
#include <type_traits>
template <typename T>
void foo()
{
if (std::is_same<T, animal>::value) { /* ... */ } // optimizable...
}
Обычно, что совершенно неработоспособный дизайн, и вы действительно хотите специализироваться:
template <typename T> void foo() { /* generic implementation */ }
template <> void foo<animal>() { /* specific for T = animal */ }
Отметим также, что необычно иметь функциональные шаблоны с явными (не выводимыми) аргументами. Это не неслыханно, но часто есть лучшие подходы.
Ответ 2
Я думаю, что сегодня лучше использовать, но только с С++ 17.
#include <type_traits>
template <typename T>
void foo() {
if constexpr (std::is_same_v<T, animal>) {
// use type specific operations...
}
}
Если вы используете некоторые специфические для типа операции в теле выражения if без constexpr
, этот код не будет компилироваться.
Ответ 3
В С++ 17 мы можем использовать варианты.
Чтобы использовать std::variant
, вам нужно включить заголовок:
#include <variant>
После этого вы можете добавить std::variant
в ваш код следующим образом:
using Type = std::variant<Animal, Person>;
template <class T>
void foo(Type T) {
if (std::is_same_v<T, Animal>) {
// Do stuff...
}
else {
// Do stuff...
}
}
Ответ 4
Вы можете специализировать свои шаблоны на основе того, что передавалось в их параметры следующим образом:
template <> void foo<animal> {
}
Обратите внимание, что это создает совершенно новую функцию, основанную на типе, который передается как T
. Это обычно предпочтительнее, поскольку оно уменьшает беспорядок и по существу является причиной того, что у нас есть шаблоны в первую очередь.