C ++:为什么numeric_limits适用于它不知道的类型?

时间:2017-11-27 22:22:53

标签: c++ c++11 templates typetraits numeric-limits

我创建了自己的类型,没有任何比较器,也没有std::numeric_limits的专业化。尽管如此,由于某种原因,std::numeric_limits<MyType>编译得很好。为什么c ++标准委员会定义numeric_limits模板,使其对所有类型都有效,包括非数字类型?

以下示例代码:

#include <iostream>
#include <limits>
using namespace std;

// This is an int wrapper that defaults to 666 instead of 0
class A {
public:
    int x;
public:
    A() : x(666) {}
};

int main() {
    A a = std::numeric_limits<A>::max();
    A b = std::numeric_limits<A>::max();

    std::cout << a.x << "\n" << b.x;
    // your code goes here
    return 0;
}

1 个答案:

答案 0 :(得分:13)

在模板元编程之前,添加了类模板std::numeric_limits作为来自<limits.h>的宏的替代:它是在标准的公开传播草案(~1995)中。模板元编程是由Erwin Unruh围绕斯德哥尔摩会议(1996年7月)发明的。此时,没有人想到是否可以检测到定义了类模板。相反,std::numeric_limits<T>::is_specialized将指示(在编译时)类模板对于类型T是否专用且有意义。各个成员被定义为使用合理的默认值,这可能会使代码被编译,尽管泛型将被实现,使得它不使用任何非专用类型的值。

如果{C}标准中指定了std::numeric_limits,它就不会在没有很好理由的情况下改变:任何改变都可能会破坏某人的代码 - 即使使用现在发现的技术可以更好地完成这些代码(一些其中C ++ 98真正无法使用。委员会现在不会设计这样的特征:<type_traits>中的类型特征是独立的特征 - 尽管通常仍然为具有适当默认值的所有可行类型定义。但是,由于当前定义确实有效,因此也没有理由以突破方式更改std::numeric_limits

请注意,并非std::numeric_limits<T>的所有成员都适用于所有类型T。例如,如果std::numeric_limits<T>::max()的默认构造函数不可访问,不可用或T d,则delete的使用将无法编译。所以,你最好保护访问任何成员关于类模板是否专用(使用C ++ 17):

template <typename T>
void f() {
    if constexpr (std::numeric_limits<T>::is_specialized) {
        // use of std::numeric_limits<T>::max(), min(), etc.
    }
    else {
        // implement the rquired functionality differently
    }
}