假设我有一个模板函数和两个类
class animal { } class person { } template<class T> void foo() { if (T is animal) { kill(); } }
我怎么才能查出 T 是动物? 我不想要 在运行时检查的东西。谢谢
您可以根据传递到模板参数中的内容对模板进行专门化,如下所示:
template <> void foo<animal> { }
注意,这将根据传递为 T的类型创建一个全新的函数。这通常是可取的,因为它减少了混乱,并且本质上是我们首先使用模板的原因。
T
使用 is_same:
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 表达式体中使用某些特定于类型的操作,则此代码将无法编译。
constexpr
在 C + + 17中,我们可以使用 变体。
要使用 std::variant,您需要包含标题:
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():
std::is_same()
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;