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

时间:2017-06-24 22:33:29

标签: c++ numeric limits

我想检查一个类型是否在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"
);

1 个答案:

答案 0 :(得分:2)

这是因为如果您查看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 ++不支持按值返回数组类型(参见Why doesn't C++ support functions returning arrays?

因此以下行不会编译

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

现在它会工作,因为你已经明确地将数组类型衰减为指针,并且可以从函数返回。您可能首先想要这样做,因为您不希望不小心为std::numeric_limits::is_specialized 等非腐朽类型调用const int&