检查整体类型

Check for integral type

本文关键字:类型 检查      更新时间:2023-10-16

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

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

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

我也知道Boost提供了这个功能。我对如何"手动"进行此检查感兴趣。

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

手动来说,你必须首先定义一个模板类来定义某物是否在编译时为 false:

template<bool B>
struct bool_type {
    static const bool value = B;
};
typedef bool_type<true> true_type;
typedef bool_type<false> false_type;

之后,您开始定义具有默认情况和一些重定向情况的 trait 类:

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

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

这可能是"仅链接"的答案,但恕我直言,它回答了这个问题,

可能的实现:

第 151 行从 GCC 4.8.1 在线文档 256

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

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

我给出了两种方法来测试值(而不是类型)。 一个使用 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;
}