Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading (not specializing) templates in std namespace

This is very pedantic but in C++03 it was apparently non-conforming for a program to overload (not specialize) a template function in the std namespace: see mention of this here and long discussion on comp.lang.c++.moderated

i.e. this was ok:

namespace std
{
    template <>
    void swap (Foo & f, Foo & g)
    {
       // ...
    }
}

but this was not (if I understand correctly...):

namespace std
{
    template <typename T>
    void swap (TempateFoo<T> & f, TempateFoo<T> & g)
    {
       // ...
    }
}

Is this still true in C++11? Also, does this apply to template classes (like std::hash) too, or just template functions?

EDIT: also, is there any example of a standard library implementation such that the latter would break things in practice? And if not, is there a specific reason for disallowing overloads like in the second case above? (what could potentially break in theory?)

like image 241
Stephen Lin Avatar asked Feb 27 '13 05:02

Stephen Lin


2 Answers

It is not possible to define a partial specialization of a function template in C++, so your second example defines an overload not a specialization. Since the standard only allows specializations to be added to namespace std, your overload is illegal.

Is this still true in C++11?

Yes.

Also, does this apply to template classes (like std::hash) too, or just template functions?

You can't overload class templates anyway, you can only overload functions. The same rules apply though, you can only specialize a class template if the specialization depends on a user-defined (meaning non-standard) type.

is there a specific reason for disallowing overloads like in the second case above? (what could potentially break in theory?)

As one example, the implementation might want to take the address of a function but if you've overloaded the function then taking the address could cause an ambiguity and fail to compile, meaning you've just broken valid code in the standard library.

like image 102
Jonathan Wakely Avatar answered Oct 21 '22 03:10

Jonathan Wakely


n3376 17.6.4.2.1

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.

17.6.4.2.2

The behavior of a C++ program is undefined if it declares

— an explicit specialization of any member function of a standard library class template, or

— an explicit specialization of any member function template of a standard library class or class template, or

— an explicit or partial specialization of any member class template of a standard library class or class template.

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.

like image 6
ForEveR Avatar answered Oct 21 '22 03:10

ForEveR