6

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.

4

1 回答 1

4

从技术角度来看,没有理由std::numeric_limits<T>不能使用引用。所有需要它来添加这样的部分专业化:

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

当然,用户不能添加这些专业。但是,这并不是一个很大的限制,因为numeric_limits可以在合适的命名空间中创建自定义变体。

由于它在技术上是可行的,现在的问题变成了为什么标准不提供这些声明。我认为不会有一个决定性的答案(除非这个想法被讨论并丢弃了一个合适且仍然可以访问的记录)。以下是一些可能的答案:

  1. 未提出该功能。引入时std::numeric_limits,它专门针对用<limits.h>更多的 C++ 方法替换宏。不存在类似decltype(expr)和转发引用的东西,即模板参数不会被“意外”推断为引用类型。因此,删除限定符在当时并不是一个问题。
  2. 我不确定在历史numeric_limits上添加部分模板专业化时是否已经存在。即使它存在,任何类似模板元编程的东西都不存在。因此,可能不可能或假定不可能以必要的方式干预模板参数类型。
  3. 即使考虑了,我怀疑委员会是否会添加部分专业化:numeric_limits<T>检查类型的特征,T但引用类型没有max()or digits。此外,如果支持引用类型,因为“显然”所需的属性必须是要停止的基础类型之一:也应该std::numeric_limits<int*>::max()提供与 相同的值std::numeric_limits<int>::max()吗?毕竟,它对指针也没有任何意义。
  4. 考虑到最初的提议几乎肯定没有涵盖合格类型的情况(见上文),该功能不可用的另一个原因是它根本没有被提议:没有提议,标准不会改变。如果提出该功能,标准是否会改变是一个单独的问题。在这个一般空间(P0437r0)中有一个提案,但浏览它我认为这个提案也不包括合格的类型。
于 2018-08-20T07:53:22.887 回答