A textbook I have notes that you can provide your own implementation for standard library functions like swap(x,y) via template specialization or function overloading. This would be useful for any types which can benefit from something other than an assignment swap, like STL containers for example (which already have swaps written, I know).
My questions are the following:
-
What’s better: template specialization to give your specialized
swap implementation, or function overloading providing the exact
parameters you wish to use without a template? -
Why is it better? Or if they’re equal, why is this?
Short story: overload when you can, specialise when you need to.
Long story: C++ treats specialisation and overloads very differently. This is best explained with an example.
Now let’s swap the last two.
The compiler does overload resolution before it even looks at specialisations. So, in both cases, overload resolution chooses
foo(T*). However, only in the first case does it findfoo<int*>(int*)because in the second case theint*specialisation is a specialisation offoo(T), notfoo(T*).You mentioned
std::swap. This makes things even more complicated.The standard says that you can add specialisations to the
stdnamespace. Great, so you have someFootype and it has a performant swap then you just specialiseswap(Foo&, Foo&)in thestdnamespace. No problems.But what if
Foois a template class? C++ doesn’t have partial specialisation of functions, so you can’t specialiseswap. Your only choice is overloading, but the standard says that you aren’t allowed to add overloads into thestdnamespace!You have two options at this point:
Create a
swap(Foo<T>&, Foo<T>&)function in your own namespace, and hope that it gets found via ADL. I say “hope” because if the standard library calls swap likestd::swap(a, b);then ADL simply won’t work.Ignore the part of the standard that says not to add overloads and do it anyway. Honestly, even though it’s technically not allowed, in all realistic scenarios it’s going to work.
One thing to remember though is that there’s no guarantee that the standard library uses
swapat all. Most algorithms usestd::iter_swapand in some implementations that I’ve looked at, it doesn’t always forward tostd::swap.