std::numeric_limits<T>
的文档说它不应该专门针对非基本类型。数字式用户定义类型怎么样?如果我定义自己的类型T
表示一个数值并重载数字运算符,并且numeric_limits
表示的信息是有意义的 - 如果我将numeric_limits
专门用于那个,那么会有什么破坏吗类型?
答案 0 :(得分:19)
来吧,没有什么不好的事情会发生。
C ++标准广泛保护C ++ 11 17.6.4.2.1中的::std
命名空间,但在第1和第2段中特别允许您的情况:
如果C ++程序向名称空间std或a添加声明或定义,则它的行为是未定义的 除非另有说明,否则命名空间std中的命程序可以添加模板专业化 对于任何标准库模板到命名空间std,仅当声明取决于用户定义的类型时 并且专业化符合原始模板的标准库要求,并未明确说明 禁止的。
[...]程序可以仅在声明时显式实例化标准库中定义的模板 取决于用户定义类型的名称,实例化符合标准库要求 对于原始模板。
旧的C ++ 03在17.4.3.1/1中有类似的定义:
C ++程序未定义向名称空间std或名称空间添加声明或定义 在命名空间std内,除非另有说明。程序可以为任何程序添加模板特化 标准库模板到命名空间std。这种专业化(完全或部分)的标准 库模板导致未定义的行为,除非声明取决于用户定义的名称 外部链接,除非专业化符合原始模板的标准库要求。
在超越这个基本的垫脚之后,你已经指出,C ++ 03 18.2.1 / 4禁止某些类型::std::numeric_limits
的特化:
非基本标准类型,例如complex(26.2.2),不应具有专业化。
更新的C ++ 11 18.3.2.1/4的措辞略有不同:
非算术标准类型,例如
complex<T>
(26.4.2),不应具有专业化。
然而,这两个公式都允许非标准类型的特化,T
,因为你自己定义了它(正如@BoPersson在评论中已经指出的那样)。
C ++ 11 18.3.2.3/1暗示您应该(但不要求您)确保您的专业化有所有成员。
此外,您可能希望确保您的专业化不违反C ++ 11 18.3.2.3/2:
cv限定类型cv T上numeric_limits的特化成员的每个成员的值应相等 到非限定类型T的专业化对应成员的值。
这实际上意味着,如果您希望将其专门用于T
,那么您也应该对T const
,T volatile
和T const volatile
这样做。
答案 1 :(得分:10)
只是一个例子:
namespace std {
template<> class numeric_limits<Temperature> {
public:
static Temperature lowest() {return Temperature(-273.15f);};
// One can implement other methods if needed
};
}
答案 2 :(得分:1)
您可能不会将std :: numeric_limits专门用于用户定义的类型。用户定义的类型不是算术类型。 C ++标准中有明确的文字
1 numeric_limits类模板提供了一个C ++程序 有关实施的各种属性的信息 算术类型的表示。
,例如
4非算术标准类型,如复杂(26.4.2),应 没有专业。