How to check for the type of a template parameter?
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.
How do I check types within a template class in c++?
Use type traits (and if constexpr
) instead of typeid
. For example:
void g_char(const char*);
void g_wchar_t(const wchar_t*);
template <typename T>
void f(T)
{
if constexpr (std::is_same_v<T, const char*>)
{
g_char(T());
}
else if constexpr (std::is_same_v<T, const wchar_t*>)
{
g_wchar_t(T());
}
}
http://coliru.stacked-crooked.com/a/08e9e66ed5c776a4
The reason a switch doesn't work here is that the condition must be implicitly convertible to an integral type, and std::type_info
(what typeid
returns) isn't.
But then if you try keeping the typeid
expressions, you have the problem of compile-time type checking when you try calling drawText
or drawBitmap
. Both calls must be valid unless you use constexpr branches (if constexpr
). However, the conditions must then be compile-time constants, where typeid
cannot be used. So instead, you can use type traits, and in particular, std::is_same
.
Check for the type of a template parameter and use another template
You can try using template specialization to decide which function to call, eg:
template <typename T>
struct helper {
static std::string MyHelperFunction(...) {
return "";
}
};
template <typename T>
struct helper<Struct1<T>> {
static std::string MyHelperFunction(...) {
return MyHelperFunction1<Struct1<T>>(...);
}
};
template <typename T>
struct helper<Struct2<T>> {
static std::string MyHelperFunction(...) {
return MyHelperFunction2<Struct2<T>>(...);
}
};
template <class C>
std::string MyFunction(...) {
helper<C>::MyHelperFunction(...);
...
}
C++ detect if type has template parameter
I'd use the power of overload sets:
#include <iostream>
#include <type_traits>
struct foo {};
template<typename T> struct bar {};
template<template<class ...> class T, class... TArgs>
constexpr bool is_template() { return true; }
template<class T>
constexpr bool is_template() { return false; }
int main()
{
std::cout << is_template<foo>() << '\n'; // 0
std::cout << is_template<bar>() << '\n'; // 1
}
Let to the user: use the template function to provide a trait ;)
Is it possible to check if a type has been instantiated with a specific template parameter?
Not sure to understand what do you exactly want... but I suppose is something as
template <class check, template<class...> class TypeToCheck, class... T>
constexpr bool does_obj_contain_type(TypeToCheck<T...>) {
return (std::is_same_v<check, T> || ...);
}
// ...
using T = Empty<int, double>;
auto x = does_obj_contain_type<double>(T{});
But it's a problem if you can't instantiate an object of type T
. In the case, I suppose you can use class/struct specialization.
Something as
template <typename>
struct does_obj_contain_type;
template <template <typename...> class TTC, typename ... Ts>
struct does_obj_contain_type<TTC<Ts...>>
{
template <typename check>
static constexpr bool func ()
{ return (std::is_same_v<check, Ts> || ...); }
};
// ...
using T = Empty<int, double>;
constexpr auto x = does_obj_contain_type<T>::func<double>();
Or maybe better as a template variable value
(suggested by super: thanks!)
template <template <typename...> class TTC, typename ... Ts>
struct does_obj_contain_type<TTC<Ts...>>
{
template <typename Check>
static constexpr auto value = (std::is_same_v<Check, Ts> || ...);
};
// ...
using T = Empty<int, double>;
constexpr auto x = does_obj_contain_type<T>::value<double>;
Related Topics
C++11 Initializer List Fails - But Only on Lists of Length 2
Calling a Function for Each Variadic Template Argument and an Array
Dynamic Aligned Memory Allocation in C++11
Why Doesn't Narrowing Conversion Used with Curly-Brace-Delimited Initializer Cause an Error
How to Validate an Integer Input
Implementing a No-Op Std::Ostream
C++ Compiler Error C2280 "Attempting to Reference a Deleted Function" in Visual Studio 2013 and 2015
Allocating More Memory Than There Exists Using Malloc
Detect 32-Bit or 64-Bit of Windows
Std::Sort Does Not Always Call Std::Swap
Template Partial Ordering - Why Does Partial Deduction Succeed Here
Performance of Unsigned VS Signed Integers