检查整体类型

时间:2014-11-15 04:45:14

标签: c++ templates c++03 typechecking

如何检查模板参数类型是否为完整的?

我知道我可以在C ++ 11中使用std::is_integral<>来执行此操作。这里甚至还有一个问题。

How to check that template's parameter type is integral?

我也知道Boost提供此功能。我对如何&#34;手动&#34;感兴趣做这个检查。

我试图解决没有具体问题。这是一个关于C ++的抽象问题。

3 个答案:

答案 0 :(得分:4)

手动说你必须先定义一个定义是否有东西的模板类 在编译时是假的:

template<bool B>
struct bool_type {
    static const bool value = B;
};

typedef bool_type<true> true_type;
typedef bool_type<false> false_type;

之后,您开始使用默认案例和一些重定向案例来定义特征类:

template<typename T>
struct is_integral : false_type {};

template<typename T>
struct is_integral<const T> : is_integral<T> {};

template<typename T>
struct is_integral<volatile T> : is_integral<T> {};

然后,它的核心将通过手动实例化整数类型的模板特化来实现。

template<>
struct is_integral<int> : true_type {};

template<>
struct is_integral<long> : true_type {};

// etc

无论如何,这是一种方法。您可以使用一个宏来自动生成这些宏以使其更容易。然而,基本思想保持不变,他们只是检查特定类型是否是您要求的组的一部分,并通过某种查找来完成。这种方式(显式模板实例化)可能是最简单的方法。

答案 1 :(得分:1)

这可能是&#34;仅链接&#34; 答案,但恕我直言,它回答了问题,

可能的实施:

151 行<{3}}

请参阅第151行上面编码的其他typedef

答案 2 :(得分:0)

您可以执行以下操作来确定数字类型是否为整数或可以包含小数部分。此代码不会使用非数字类型进行编译,但可以添加进一步的元编程以过滤任意类型(如果这是您想要的)。这也可以修改为提供“true”类型或“false”类型(如Rapptz'答案)而不是静态bool值。

我提供了两种测试值(而不是类型)的方法。一个使用decltype获取类型,另一个使用模板函数。如果decltype不可用,则可以使用该函数,但其​​结果可能只能在运行时使用(如果不是decltype,则constexpr可能不可用)。

并确保清楚:VALUE_IS_INTEGER宏和value_is_integer模板函数不测试给定值是否为整数,它们测试值的类型是否为整数。

#include <iostream>

template <typename T, bool IS_INTEGRAL = T(3)/T(2)<=T(1) || T(3)/T(2)>=T(2)>
   struct IsIntegerTypeCheck {
   static const bool is_integer = IS_INTEGRAL;
};

#define TYPE_IS_INTEGER(type)   (IsIntegerTypeCheck<type>::is_integer)
#define VALUE_IS_INTEGER(value) (IsIntegerTypeCheck<decltype(value)>::is_integer)

template <typename T> static bool value_is_integer(const T& value) {
    return IsIntegerTypeCheck<T>::is_integer; 
}

template <typename ST>
void dump_bool(ST message, bool value) {
    std::cout << message << ' ' << (value ? "true" : "false") << "\n";
}

int main() {
    static const bool   int_is_integer = TYPE_IS_INTEGER(int);
    static const bool   float_is_integer = TYPE_IS_INTEGER(float);
    static const long   unity = 1;
    static const double tau = 3.1415925 * 2;
    static const bool   unity_is_integer = VALUE_IS_INTEGER(unity);
    static const bool   tau_is_integer = value_is_integer(tau);
    dump_bool("int is integer:  ", int_is_integer);
    dump_bool("float is integer:", float_is_integer);
    dump_bool("unity is integer:", unity_is_integer);
    dump_bool("tau is integer:  ", tau_is_integer);
    return 0;
}