假设我有一个模板函数和两个类
class animal {
}
class person {
}
template<class T>
void foo() {
if (T is animal) {
kill();
}
}
我该如何检查T是动物?我不想在运行时进行检查。谢谢
Answers:
用途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 */ }
还请注意,具有带有显式(非推论)参数的函数模板是不寻常的。这并非闻所未闻,但通常有更好的方法。
T
没有推论,所以您无能为力。您可以不使用主模板并创建专门化模板,也可以使用添加静态断言is_same
。
我认为,今天最好使用,但仅适用于C ++ 17。
#include <type_traits>
template <typename T>
void foo() {
if constexpr (std::is_same_v<T, animal>) {
// use type specific operations...
}
}
如果在if主体中不使用某些类型特定的操作,则constexpr
此代码将无法编译。
std::is_same<T, U>::value
您可以使用更短的时间:std::is_same_v<T, U>
在C ++ 17中,我们可以使用variants。
要使用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...
}
}
type
这是type的值Type
或此处is_same_v
没有意义的模板)在的上下文中没有意义variant
。相应的“特征”为holds_alternative
。
std::variant
这里完全没有必要
您可以根据传递给模板参数的内容来专门化模板,如下所示:
template <> void foo<animal> {
}
请注意,这基于传递为的类型创建了一个全新的函数T
。通常这是可取的,因为它可以减少混乱,并且从本质上讲就是我们首先使用模板的原因。