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
.