Reputation: 1133
I've been trying to answer the question in the title, but I'm stumped. Basically, trying to see if there's a built-in way to tell the 'source' of a template instantiation, at least for classes. Here is an example of what I'd like to do:
template<class T>
class A { };
auto a = A<int>();
template<class T>
auto someFunction(T item) {
if(/* if type of a is from the templated class A */) {
// yep A<int> is 'from' A.
}
}
Is this possible, in some way such as this? I could use some saved value or inheritance shenanigans to get something similar, but I'd rather not.
Upvotes: 0
Views: 82
Reputation: 218238
An other way, allowing derived class to match:
template <typename T>
std::true_type is_an_A_impl(A<T>*);
std::false_type is_an_A_impl(...);
template <typename T>
using is_a_A = decltype(is_an_A_impl(std::declval<T*>()));
Upvotes: 1
Reputation: 66230
Maybe with a custom type traits.
Something as follows
template <typename>
struct is_A : public std::false_type
{ };
template <typename T>
struct is_A<A<T>> : public std::true_type
{ };
// ...
template <typename T>
auto someFunction(T item) {
if( is_A<T>::value ) {
// yep A<int> is 'from' A.
}
}
Or, maybe, you want intercept non only A<T>
but, generically, all types that are a template type, maybe with an undefined number of template arguments?
In this case you can try with something as follows
template <typename>
struct is_template : public std::false_type
{ };
template <template <typename...> class C, typename ... Ts>
struct is_template<C<Ts...>> : public std::true_type
{ };
Problem: this type traits intercepts all template types with types template arguments and only template arguments. But doesn't intercept, by example, std::integer_sequence<int, 0, 1, 2, 3, 4, 5>
that receive a type and some non-type template parameter.
You can add other specializations for is_template
, to intercept other cases, but you can't define a specialization that catch all template types (all combinations of template parameters).
Upvotes: 4
Reputation: 123253
Use a type trait
#include <type_traits>
#include <iostream>
template<class T>
class A { };
auto a = A<int>();
template <typename X>
struct is_from_A : std::false_type {};
template <typename T>
struct is_from_A<A<T>> : std::true_type {};
int main() {
std::cout << is_from_A<int>::value << "\n"; // 0
std::cout << is_from_A<A<int>>::value << "\n"; // 1
}
Upvotes: 1