C++:为什么 numeric_limits 在它不知道的类型上工作?
C++: Why does numeric_limits work on types it does not know?
我创建了自己的类型,没有任何比较器,也没有 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;
}
添加 class 模板 std::numeric_limits
作为 <limits.h>
中的宏的替代品,在模板元编程成为现实之前:它在 pre-standard 公开发行草稿(~1995)。模板元编程是由 Erwin Unruh 在斯德哥尔摩会议(1996 年 7 月)前后发明的。在这一点上,没有人想到是否可以检测到定义了一个 class 模板。相反,std::numeric_limits<T>::is_specialized
将指示(在 compile-time)class 模板是否专门针对类型 T
是否有意义。各种成员被定义为使用合理的默认值,这将使它可能编译代码,尽管将实现泛型,以便它不使用非专用类型的任何值。
std::numeric_limits
像 C++ 标准中那样被指定,如果没有一个很好的理由,它不会改变:任何改变都可能破坏某人的代码——即使这个代码可以用现在发现的技术做得更好(其中一些在 C++98 中确实不可用)。委员会现在不会像这样设计特征:<type_traits>
中的类型特征是 stand-alone 特征——尽管通常仍然为所有具有合适默认值的可行类型定义。但是,也没有理由以中断方式更改 std::numeric_limits
,因为当前定义确实有效。
请注意,并非 std::numeric_limits<T>
的所有成员都对所有类型 T
有效。例如,如果 T
的默认构造函数不可访问、不可用或 delete
d,则使用 std::numeric_limits<T>::max()
将无法编译。因此,您最好避免访问任何成员,以了解 class 模板是否专门化(使用 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
}
}
我创建了自己的类型,没有任何比较器,也没有 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;
}
添加 class 模板 std::numeric_limits
作为 <limits.h>
中的宏的替代品,在模板元编程成为现实之前:它在 pre-standard 公开发行草稿(~1995)。模板元编程是由 Erwin Unruh 在斯德哥尔摩会议(1996 年 7 月)前后发明的。在这一点上,没有人想到是否可以检测到定义了一个 class 模板。相反,std::numeric_limits<T>::is_specialized
将指示(在 compile-time)class 模板是否专门针对类型 T
是否有意义。各种成员被定义为使用合理的默认值,这将使它可能编译代码,尽管将实现泛型,以便它不使用非专用类型的任何值。
std::numeric_limits
像 C++ 标准中那样被指定,如果没有一个很好的理由,它不会改变:任何改变都可能破坏某人的代码——即使这个代码可以用现在发现的技术做得更好(其中一些在 C++98 中确实不可用)。委员会现在不会像这样设计特征:<type_traits>
中的类型特征是 stand-alone 特征——尽管通常仍然为所有具有合适默认值的可行类型定义。但是,也没有理由以中断方式更改 std::numeric_limits
,因为当前定义确实有效。
请注意,并非 std::numeric_limits<T>
的所有成员都对所有类型 T
有效。例如,如果 T
的默认构造函数不可访问、不可用或 delete
d,则使用 std::numeric_limits<T>::max()
将无法编译。因此,您最好避免访问任何成员,以了解 class 模板是否专门化(使用 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
}
}