我创建了自己的类型,没有任何比较器,也没有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;
}
答案 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
}
}