如何检查模板参数的类型?

假设我有一个模板函数和两个类

class animal {
}
class person {
}


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

我怎么才能查出 T 是动物? 我不想要 在运行时检查的东西。谢谢

163477 次浏览

您可以根据传递到模板参数中的内容对模板进行专门化,如下所示:

template <> void foo<animal> {


}

注意,这将根据传递为 T的类型创建一个全新的函数。这通常是可取的,因为它减少了混乱,并且本质上是我们首先使用模板的原因。

使用 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 */ }

还要注意的是,函数模板很少有明确的(非推导的)参数。这并非闻所未闻,但通常有更好的方法。

我觉得现在用起来比较好,但是只能用 C + + 17。

#include <type_traits>


template <typename T>
void foo() {
if constexpr (std::is_same_v<T, animal>) {
// use type specific operations...
}
}

如果在没有 constexpr的 If 表达式体中使用某些特定于类型的操作,则此代码将无法编译。

在 C + + 17中,我们可以使用 变体

要使用 std::variant,您需要包含标题:

#include <variant>

然后,您可以在代码中添加 std::variant,如下所示:

using Type = std::variant<Animal, Person>;


template <class T>
void foo(Type type) {
if (std::is_same_v<type, Animal>) {
// Do stuff...
} else {
// Do stuff...
}
}

std::is_same()只有在 C + + 11之后才能使用。对于 C + + 11之前的版本,你可以使用 typeid():

template <typename T>
void foo()
{
if (typeid(T) == typeid(animal)) { /* ... */ }
}

使用 c + + 概念 Https://en.cppreference.com/w/cpp/language/constraints

例如只接收字符类型的类

#include <concepts>


template<typename Type>
concept CharTypes = std::is_same<Type, char>::value ||
std::is_same<Type, wchar_t>::value || std::is_same<Type, char8_t>::value ||
std::is_same<Type, char16_t>::value || std::is_same<Type, char32_t>::value;


template<CharTypes T>
class Some{};


是的,这样不行


Some<int> s;