18

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

1 回答 1

15

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

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

请注意,并非所有成员std::numeric_limits<T>都对所有类型都有效T。例如,如果的默认构造函数不可访问、不可用或d. ,则使用 ofstd::numeric_limits<T>::max()将无法编译。因此,您最好不要保护对任何成员的访问,以了解类模板是否是专用的(使用 C++17):Tdelete

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
    }
}
于 2017-11-27T23:28:12.313 回答