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

toh*_*ava 17 c++ templates type-traits numeric-limits c++11

我创建了自己的类型,没有任何比较器,没有专业化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;
}
Run Code Online (Sandbox Code Playgroud)

Die*_*ühl 14

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

随着std::numeric_limits像在C++标准也不会更改,恕不一个很好的理由被指定:任何改变可能会打破别人的代码-即使该代码可以完成与现在发现的技术更好(其中一些是用C +真正不可用+98).委员会现在不会设计这样的特征:类型特征<type_traits>是独立的特征 - 尽管通常仍然为具有适当默认值的所有可行类型定义.但是,由于std::numeric_limits当前的定义确实有效,因此也没有理由以突破方式进行更改.

请注意,并非所有成员std::numeric_limits<T>都适用于所有类型T.例如,std::numeric_limits<T>::max()如果T默认构造函数不可访问,不可用或deleted ,则使用将无法编译.所以,你最好保护访问任何成员关于类模板是否专用(使用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
    }
}
Run Code Online (Sandbox Code Playgroud)