检测<T>某些非数字类型 T 的 std::numeric::type 的特化

Detecting specialization of std::numeric::type<T> for some non numeric type T

本文关键字:std numeric type gt lt 数字 检测 类型      更新时间:2023-10-16

我想检查一个类型是否有 std::numeric_limits 中的条目。 当类型是数组时 - (或者可能不是数字?我收到编译器错误。 这使我无法根据 std::numeric_limits 中是否支持该类型进行检测和分支。 我将不胜感激任何人想分享的任何见解。

// the following provokes compiler error on Clang
// Function cannot return array type 'type' (aka 'char [20]')
static_assert(
! std::numeric_limits<char[20]>::is_specialized,
"! std::numeric_limits<char[20]>::is_specialized"
);
// invokes static assert on compile as expected
static_assert(
std::numeric_limits<char[20]>::is_specialized,
"std::numeric_limits<char[20]>::is_specialized"
);

发生这种情况是因为如果您查看内部std::numeric_limits或查看文档,您将看到如下所示的方法声明

template<class T>
class numeric_limits
{
public:
static constexpr bool is_specialized = false;
static constexpr T min() noexcept;
static constexpr T max() noexcept;
static constexpr T lowest() noexcept;

在这里,如您所见,有些函数按值返回T,C++不支持按值返回数组类型(请参阅为什么C++不支持返回数组的函数?

所以下面的行不会编译

std::numeric_limits<char[20]>::is_specialized

任何直接检查is_specialized是否适用于直接使用 SFINAE 的类型的任何进一步尝试都不会编译,因为会产生错误(因为如上所述返回数组类型)不在模板的直接上下文中。 因此,您需要检查std::numeric_limits支持的概念(在本例中为std::is_arithmetic)

但是,要完成这项工作,您需要做的就是std::decay_t类型

std::numeric_limits<std::decay_t<char[20]>>::is_specialized

现在它将起作用,因为您已将数组类型显式衰减为指针,并且可以从函数返回。 您可能首先想这样做,因为您不想意外地为像const int&这样的非衰减类型调用std::numeric_limits::is_specialized