Reputation: 3388
Suppose I have a template function and two classes
class animal {
}
class person {
}
template<class T>
void foo() {
if (T is animal) {
kill();
}
}
How do I do the check for T is animal? I don't want to have something that checks during the run time. Thanks
Upvotes: 148
Views: 217469
Reputation: 973
I think todays, it is better to use, but this only works with C++17 or later.
#include <type_traits>
template <typename T>
void foo() {
if constexpr (std::is_same_v<T, animal>) {
// use type specific operations...
}
}
If you use some type specific operations in if expression body without constexpr
, this code will not compile.
Upvotes: 70
Reputation: 33
use c++ concepts https://en.cppreference.com/w/cpp/language/constraints
for example class who recive only char types
#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{};
and yes, this not working
Some<int> s;
Upvotes: 2
Reputation: 21509
std::is_same()
is only available since C++11. For pre-C++11 you can use typeid()
:
template <typename T>
void foo()
{
if (typeid(T) == typeid(animal)) { /* ... */ }
}
Upvotes: 13
Reputation: 959
In C++17, we can use variants.
To use std::variant
, you need to include the header:
#include <variant>
After that, you may add std::variant
in your code like this:
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...
}
}
Upvotes: 7
Reputation: 10490
You can specialize your templates based on what's passed into their parameters like this:
template <> void foo<animal> {
}
Note that this creates an entirely new function based on the type that's passed as T
. This is usually preferable as it reduces clutter and is essentially the reason we have templates in the first place.
Upvotes: 10
Reputation: 477600
Use is_same
:
#include <type_traits>
template <typename T>
void foo()
{
if (std::is_same<T, animal>::value) { /* ... */ } // optimizable...
}
Usually, that's a totally unworkable design, though, and you really want to specialize:
template <typename T> void foo() { /* generic implementation */ }
template <> void foo<animal>() { /* specific for T = animal */ }
Note also that it's unusual to have function templates with explicit (non-deduced) arguments. It's not unheard of, but often there are better approaches.
Upvotes: 197