是否可以将std :: numeric_limits <t>专门用于用户定义的类似数字的类?</t>

时间:2013-04-20 17:01:58

标签: c++ types numbers standards

std::numeric_limits<T>的文档说它不应该专门针对非基本类型。数字式用户定义类型怎么样?如果我定义自己的类型T表示一个数值并重载数字运算符,并且numeric_limits表示的信息是有意义的 - 如果我将numeric_limits专门用于那个,那么会有什么破坏吗类型?

3 个答案:

答案 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 constT volatileT 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),应   没有专业。