The C++ standard prohibits declaring types or defining anything in namespace std
, but it does allow you to specialize standard STL templates for user-defined types.
Usually, when I want to specialize std::swap
for my own custom templated type, I just do:
namespace std
{
template <class T>
void swap(MyType<T>& t1, MyType<T>& t2)
{
t1.swap(t2);
}
}
...and that works out fine. But I'm not entirely sure if my usual practice is standard compliant. Am I doing this correctly?
Edit
See Scott Meyer's article: See Effective C++ 3rd Edition, item 25: Consider support for a non-throwing swap (p106-p112) for a confirmation of my answer.
Original answer
Scott Meyers wrote about this, so my answer comes from memory.
First, define a swap function in the namespace of your class. For example :
Then, if possible (it is not always possible for templated classes (*) ), specialize the swap function in the namespace std. For example :
The, when using the swap function, do it indirectly, importing the std swap function into your scope. For example :
As soon as I have access to my books, I'll post here the exact reference.
Why won't you just define swap in MyType's namespace and exploit argument-dependent lookup power?
Because of argument dependent (aka Koenig) lookup, I believe you can specify your own swap in the namespace of the type you want it for and it will be found in preference to
::std::swap
. Also, I believe the template for::std::swap
will expand differently for classes that have their own swap member function and so you can add that member function to the class and that will be used for your type.What you have is not a specialization, it is overloading and exactly what the standard prohibits. (However, it will almost always currently work in practice, and may be acceptable to you.)
Here is how you provide your own swap for your class template:
And here is how you call swap, which you'll notice is used in Ex's swap too:
Related: Function template specialization importance and necessity
Define own
swap
. This function must call std::swap for any type T except your types.Define your type and your swap function in the same namespace: