Подтвердить что ты не робот

Как проверить тип параметра шаблона?

Предположим, что у меня есть функция шаблона и два класса

class animal {
}
class person {
}

template<class T>
void foo() {
  if (T is animal) {
    kill();
  }
}

Как сделать проверку для T - это животное? Я не хочу иметь то, что проверяется во время выполнения. Благодаря

4b9b3361

Ответ 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. Это обычно предпочтительнее, поскольку оно уменьшает беспорядок и по существу является причиной того, что у нас есть шаблоны в первую очередь.