is it ok to specialize std::numeric_limits for

2020-01-31 18:40发布

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?

3条回答
Juvenile、少年°
2楼-- · 2020-01-31 19:15

Short answer:

Go ahead, nothing bad will happen.

Long answer:

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:

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.

The older C++03 has a similar definition in 17.4.3.1/1:

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.

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:

Non-fundamental standard types, such as complex (26.2.2), shall not have specializations.

The more current C++11 18.3.2.1/4 has a slightly different wording:

Non-arithmetic standard types, such as complex<T> (26.4.2), shall not have specializations.

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).

Caveats

C++11 18.3.2.3/1 hints that you should (but does not require you to) ensure that your specialization has all members.

Also, you may wish to ensure that C++11 18.3.2.3/2 is not violated by your specialization:

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.

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.

查看更多
萌系小妹纸
3楼-- · 2020-01-31 19:22

Just an example:

namespace std {
    template<> class numeric_limits<Temperature> {
    public:
       static Temperature lowest() {return Temperature(-273.15f);};
       // One can implement other methods if needed
    };
}
查看更多
够拽才男人
4楼-- · 2020-01-31 19:27

You may not specialize std::numeric_limits for a user-defined type. A user defined type is not an arithmetic type. There is clear written in the C++ Standard that

1 The numeric_limits class template provides a C++ program with information about various properties of the implementation’s representation of the arithmetic types.

and for example

4 Non-arithmetic standard types, such as complex (26.4.2), shall not have specializations.

查看更多
登录 后发表回答