问题描述
std::numeric_limits
的文档说它不应该专门用于非基本类型.类似数字的用户定义类型呢?如果我定义自己的类型 T
表示数值并重载数字运算符,并且 numeric_limits
表示的信息有意义 - 如果我专门化 T
该类型的代码>numeric_limits?
The documentation of std::numeric_limits<T>
says it should not be specialized for non-fundamental types. What about number-like user-defined types? If I define my own type T
which represents a numeric value and overloads numeric operators, and for which the information represented by numeric_limits
makes sense -- will anything break if I specialize numeric_limits
for that type?
推荐答案
简答:
去吧,不会有什么不好的事情发生.
Short answer:
Go ahead, nothing bad will happen.
C++ 标准广泛保护 C++11 17.6.4.2.1 中的 ::std
命名空间,但特别允许您在第 1 段和第 2 段中的情况:
The C++ standard extensively protects the ::std
namespace in C++11 17.6.4.2.1, but specifically allows your case in paragraphs 1 and 2:
如果 C++ 程序将声明或定义添加到命名空间 std 或添加到命名空间 std 内的命名空间,除非另有说明.程序可以添加模板专业化仅当声明依赖于用户定义的类型时,任何标准库模板到命名空间 std并且专业化满足原始模板的标准库要求并且没有明确禁止.
The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.
[...] 程序可以显式实例化标准库中定义的模板,仅当声明取决于用户定义类型的名称并且实例化满足标准库要求为原始模板.
[...] A program may explicitly instantiate a template defined in the standard library only if the declaration depends on the name of a user-defined type and the instantiation meets the standard library requirements for the original template.
较旧的 C++03 在 17.4.3.1/1 中有类似的定义:
The older C++03 has a similar definition in 17.4.3.1/1:
C++ 程序向命名空间 std 或命名空间添加声明或定义是未定义的在命名空间 std 内,除非另有说明.一个程序可以为任何添加模板特化标准库模板到命名空间 std.标准的这种专门化(完全或部分)除非声明依赖于用户定义的名称,否则库模板会导致未定义的行为外部链接,除非专业化满足原始模板的标准库要求.
It is undefined for a C++ program to add declarations or definitions to namespace std or namespaces within namespace std unless otherwise specified. A program may add template specializations for any standard library template to namespace std. Such a specialization (complete or partial) of a standard library template results in undefined behavior unless the declaration depends on a user-defined name of external linkage and unless the specialization meets the standard library requirements for the original template.
在通过这个基本的踏脚石之后,您已经指出,C++03 18.2.1/4 禁止对某些类型进行 ::std::numeric_limits
特化:
After getting past this fundamental stepping stone, you already pointed out, C++03 18.2.1/4 forbids specializations of ::std::numeric_limits
for certain types:
非基本的标准类型,例如复杂的 (26.2.2),不应有专门化.
Non-fundamental standard types, such as complex (26.2.2), shall not have specializations.
最新的 C++11 18.3.2.1/4 的措辞略有不同:
The more current C++11 18.3.2.1/4 has a slightly different wording:
非算术标准类型,例如 complex
(26.4.2),不应有特化.
Non-arithmetic standard types, such as
complex<T>
(26.4.2), shall not have specializations.
然而,这两种公式都允许对非标准类型进行特化,即 T
,因为您自己定义了它(正如@BoPersson 已经在评论中指出的那样).
Both of these formulations however allow specializations for non-standard types, which T
is, since you defined it yourself (as @BoPersson already pointed out in the comments).
C++11 18.3.2.3/1 提示您应该(但不要求您)确保您的专业化具有所有成员.
C++11 18.3.2.3/1 hints that you should (but does not require you to) ensure that your specialization has all members.
此外,您可能希望确保您的专业不违反 C++11 18.3.2.3/2:
Also, you may wish to ensure that C++11 18.3.2.3/2 is not violated by your specialization:
cv 限定类型 cv T 上 numeric_limits 特化的每个成员的值应相等到非限定类型 T 上特化的相应成员的值.
The value of each member of a specialization of numeric_limits on a cv-qualified type cv T shall be equal to the value of the corresponding member of the specialization on the unqualified type T.
这实质上意味着,如果您希望将其专门用于 T
,您也应该为 T const
、T volatile
和T const volatile
.
Which essentially means, that if you wish to specialize it for T
, you should also do so for T const
, T volatile
and T const volatile
.
这篇关于是否可以专门化 std::numeric_limits<T>对于用户定义的类似数字的类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!