推断类型是否来自模板类的方法

时间:2019-03-27 22:55:12

标签: c++ templates types

我一直在尝试回答标题中的问题,但我很困惑。基本上,至少在类中,尝试查看是否有内置的方式来告诉模板实例化的“源”。这是我想做的一个例子:

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.
    }
}

这有可能吗?我可以使用一些节省的价值或继承诡计来获得类似的东西,但我宁愿不这样做。

3 个答案:

答案 0 :(得分:4)

也许具有自定义类型特征。

以下内容

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.
   }
}

或者,也许,您不仅希望截获A<T>,而且通常要截获所有属于模板类型的类型,也许带有未定义数量的模板参数?

在这种情况下,您可以尝试以下操作

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
 { };

问题:此类型特征拦截所有类型为模板参数和 only 模板参数的模板类型。但是,例如,不会截获接收到类型和一些非类型模板参数的std::integer_sequence<int, 0, 1, 2, 3, 4, 5>

您可以为is_template添加其他专业化,以拦截其他情况,但是您不能定义一个能够捕获所有模板类型(模板参数的所有组合)的专业化。

答案 1 :(得分:1)

使用类型特征

#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
}

答案 2 :(得分:1)

另一种方法,允许派生类匹配:

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*>()));