C++98:编译时检测浮点类型

C++98: Compile Time Detect floating point type

本文关键字:类型 检测 编译 C++98      更新时间:2023-10-16

因此,您可以在C++98中使用以下内容制作一个伪is_integral:

template <typename T>
struct is_integral
{
  static const bool value;
};
template <typename T>
const bool is_integral<T>::value = std::numeric_limits<T>::is_integer;

很简单。。。对于浮点(不需要升压依赖性),你能做什么类似的事情吗?

C++标准*声明:

应为每种基本类型提供专业化,包括浮点和整数,包括布尔。

(*-我很难找到标准的早期草案。如果有人能在这里帮忙,我将不胜感激。)

由于std::numeric_limits提供了is_integeris_specialized的定义,因此可以结合这些信息来推断类型是否为浮点类型。

例如:

template <typename T>
struct is_floating_point
{
    static const bool value;
};
template <typename T>
const bool is_floating_point<T>::value =
    std::numeric_limits<T>::is_specialized &&  // Is fundamental arithmetic type...
    !std::numeric_limits<T>::is_integer;       // ...that is not an integer

由于只有三种浮点类型(根据C++98§3.9.1/8),因此不难枚举它们:

template <typename T>
struct is_floating_point {
  enum { value = 0 };
};
template <>
struct is_floating_point<float> {
  enum { value = 1 };
};
template <>
struct is_floating_point<double> {
  enum { value = 1 };
};
template <>
struct is_floating_point<long double> {
  enum { value = 1 };
};

类似is_integral技巧的东西:

#include <limits>
#include <iostream>
template <typename T>
struct is_floating_point
{
  static const bool value;
};
// is a fundamental type (i.e. not a user defined type) but not an integer
template <typename T>
const bool is_floating_point<T>::value =
!std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_bounded;
struct Obj
{
};
int main()
{
    std::cout << is_floating_point<float>::value << std::endl;        // 1
    std::cout << is_floating_point<int>::value << std::endl;          // 0
    std::cout << is_floating_point<Obj>::value << std::endl;          // 0
    std::cout << is_floating_point<bool>::value << std::endl;         // 0
    std::cout << is_floating_point<double>::value << std::endl;       // 1
    std::cout << is_floating_point<long double>::value << std::endl;  // 1
    // this would compile since it's an array of size 1
    int Y[is_floating_point<float>::value] = { };
    // this wouldn't compile since it's an array of size 0
    int N[is_floating_point<int>::value] = { };
}