C ++:为什么numeric_limits可以处理未知的类型? [英] C++: Why does numeric_limits work on types it does not know?

查看:82
本文介绍了C ++:为什么numeric_limits可以处理未知的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了自己的类型,没有任何比较器,也没有 std :: numeric_limits 的特殊化。尽管如此,出于某些原因, std :: numeric_limits< MyType> 可以正常编译。为什么c ++标准委员会将 numeric_limits 模板定义为对所有类型(包括非数字类型)均有效?

I have created my own type, without any comparator, and without a specialization of std::numeric_limits. Despite that, for some reason, std::numeric_limits<MyType> compiles fine. Why did the c++ standards committee define the numeric_limits template such that it is valid for all types, including non-numeric types??

以下示例代码:

#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;
}


推荐答案

类模板<$ c在模板元编程成为一件事之前,添加了$ c> std :: numeric_limits 来替换< limits.h> 中的宏:它是在标准前公开发布的草案中(〜1995年)。模板元编程由Erwin Unruh在斯德哥尔摩会议(1996年7月)上发明。此时,没有人考虑过是否可以检测到定义了类模板。相反, std :: numeric_limits< T> :: is_specialized 会(在编译时)指示类模板是否对类型 T专门化且有意义。 。各个成员被定义为使用合理的默认值,尽管可以实现泛型,但它不会对非专业类型使用任何值。尽管这样,将有可能编译代码。

The class template std::numeric_limits was added as a replacement for the macros from <limits.h> before template meta programming was a thing: it was in the pre-standard publicly circulated drafts (~1995). Template meta programming was invented by Erwin Unruh around the Stockholm meeting (July 1996). At this point nobody thought whether it could be detectable that a class template is defined. Instead, std::numeric_limits<T>::is_specialized would indicate (at compile-time) whether the class template is specialized and meaningful for type T. The various member were defined to use a reasonable default which would make it likely to get the code compiled although generic would be implemented such that it doesn't use any of the values for types which are not specialized.

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

With std::numeric_limits being specified like that in the C++ standard it wouldn't change without a very good reason: any change would likely break somebody's code - even if this code could be done better with now discovered technology (some of which was genuinely unavailable with C++98). The committee wouldn't design the traits like this now: the type traits in <type_traits> are stand-alone traits - although generally still defined for all viable types with a suitable default. However, there is also no reason to change std::numeric_limits in a breaking way as the current definition does work.

请注意,并非 std :: numeric_limits< T> 的所有成员对于所有类型 T 均有效。例如,如果 T 的使用,则 std :: numeric_limits< T> :: max()的使用将无法编译默认构造函数不可访问,不可用或删除 d。因此,关于类模板是否是专用的(使用C ++ 17),您最好避免对任何成员的访问:

Note that not all members of std::numeric_limits<T> are valid for all types T. For example use of std::numeric_limits<T>::max() will fail to compile if T's default constructor is unaccessible, unavailable, or deleted. So, you'd be best off guarding access to any of the members on whether the class template is specialized (using 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
    }
}

这篇关于C ++:为什么numeric_limits可以处理未知的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆