Is there a reason why numeric_limits do not work on reference types?

青春壹個敷衍的年華 提交于 2019-12-10 17:18:07

问题


If you mistakenly do something like:

#include<limits>
int arr[3];
auto x  = std::numeric_limits<decltype(arr[0])>::max();

You will get unhelpful error message from the file in the STL implementation.

Problem is that template argument is a reference, so the fix is to remove it:

auto x  = std::numeric_limits<std::remove_reference_t<decltype(arr[0])>>::max();

Now my question is why numeric_limits do not know to do this by themselves? I would understand that you do not want to remove pointerness(since max of char pointer and max of char are very very different things), but I would assume that whenever you have a reference as an argument to numeric_limits you would be happy with result that is obtained by removing it.


回答1:


From a technical point of view, there is no reason why std::numeric_limits<T> couldn't work with references. All what would be needed it to add a partial specialisations like this:

namespace std {
    template <typename T> struct numeric_limits<T&>: numeric_limits<T> {};
    template <typename T> struct numeric_limits<T&&>: numeric_limits<T> {};
    template <typename T> struct numeric_limits<T const>: numeric_limits<T> {};
    template <typename T> struct numeric_limits<T volatile>: numeric_limits<T> {};
    template <typename T> struct numeric_limits<T const volatile>: numeric_limits<T> {};
}

A user can't add these specialisations, of course. However, that's not a huge constraint as a custom variant of numeric_limits can be created in a suitable namespace.

As it is technically doable the question now becomes why the standard doesn't provide these declarations. I don't think there will be a conclusive answer (unless this idea was discussed and discarded with a suitable and still accessible record). Here are some of the potential answers:

  1. The feature wasn't proposed. When std::numeric_limits was introduced it specifically targeted replacing the macros in <limits.h> with a more a C++ approach. Something like decltype(expr) and forwarding references didn't exist, i.e., template arguments wouldn't be "accidentally" deduced as reference types. Thus, removing qualifiers wasn't a concern at the time.
  2. I'm not sure if at the point in history when numeric_limits were added partial template specialisation already existed. Even if it existed, anything resembling template meta programming didn't exist. As a result, it may not have been possible or assumed to be possible to meddle with the template argument type in the necessary way.
  3. Even if it were considered, I doubt the committee would have gone with adding the partial specialisations: numeric_limits<T> inspects the traits of type T but reference types don't have a max() or digits. Also, if reference types are supported because "clearly" the desired property must be the one of the underlying type where to stop: should std::numeric_limits<int*>::max() provide the same value as std::numeric_limits<int>::max(), too? After all, it also doesn't make any sense on pointers.
  4. Considering that the original proposal almost certainly didn't cover the case of qualified types (see above), another reason why the feature isn't available is that it simply wasn't proposed: without a proposal the standard won't get changed. Whether the standard would get changed if the feature were proposed is a separate question. There is a proposal in this general space (P0437r0) but browsing over it I don't think this proposal covers qualified types, either.


来源:https://stackoverflow.com/questions/51896941/is-there-a-reason-why-numeric-limits-do-not-work-on-reference-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!