如果你错误地做了类似的事情:
#include<limits>
int arr[3];
auto x = std::numeric_limits<decltype(arr[0])>::max();
您将从STL实现中的文件中获得无用的错误消息.
问题是模板参数是一个引用,所以修复是删除它:
auto x = std::numeric_limits<std::remove_reference_t<decltype(arr[0])>>::max();
现在我的问题是为什么numeric_limits不知道自己做这个?
我会理解你不想删除指针(因为最大的char指针和最大的char是非常不同的东西),但我会假设每当你有一个引用作为numeric_limits的参数时你会对结果感到满意是通过删除它获得的.
最佳答案 从技术角度来看,没有理由为什么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的自定义变体.
由于技术上可行,现在问题成为标准不提供这些声明的原因.我不认为会有一个确凿的答案(除非这个想法被讨论并以合适且仍然可访问的记录丢弃).以下是一些可能的答案:
>该功能未提出.当引入std :: numeric_limits时,它专门针对替换< limits.h>中的宏.用更多的C方法.像decltype(expr)和转发引用这样的东西不存在,即模板参数不会被“意外地”推断为引用类型.因此,当时不需要删除限定符.
>我不确定在历史记录中是否添加了numeric_limits,部分模板专门化已经存在.即使存在,也不存在任何类似于模板元编程的东西.因此,可能无法或假设可能以必要的方式插入模板参数类型.
>即使考虑到了,我也怀疑委员会是否会添加部分专业化:numeric_limits< T>检查类型T的特征,但引用类型没有max()或数字.此外,如果支持引用类型,因为“明确”所需的属性必须是要停止的基础类型之一:std :: numeric_limits< int *> :: max()提供与std :: numeric_limits<相同的值; int> :: max()也是?毕竟,它对指针也没有任何意义.
>考虑到原始提案几乎肯定不包括合格类型的情况(见上文),该功能不可用的另一个原因是它没有提出:没有提案,标准将不会改变.如果提出特征,标准是否会改变是一个单独的问题.在这个一般空间(P0437r0)中有一个提案,但浏览它我也不认为这个提案涵盖了合格的类型.