Niels Dekker (no reply address) wrote:
> When calling swap as follows (as recommanded in Effective C++, 3rd
> Edition, by Scott Meyers), what swap is chosen to be called?
> using std::swap;
> swap(a, b);
>
> Suppose there is a global ::swap function provided, whose parameter type
> matches closer to the type of a and b than any of the std::swap
> overloads does. Will this ::swap be called, or is std::swap still
> preferred?
"using std::swap" would mean std::swap would be taken into
consideration when establishing the initial overload set. Usually, when
all aspects of overload resolution are equal, non-templates would be
preferred.
> #include <algorithm>
> struct Foo {};
>
> void swap(int &, int &) {}
> void swap(Foo &, Foo &) {}
> template<typename T> void swap(T*&, T*&) {}
>
> int main()
> {
> using std::swap;
>
> int i1, i2;
> swap(i1, i2);
I would call you swap(int&,int&) a perfect match here, and would put my
money on it being called everytime.
>
> int *ptr1, *ptr2;
> swap(ptr1, ptr2);
Your (template) version of swap is more specialized than the std::swap
- therefore it should be called here (I'm using SGI std::swap as
reference).
SGI...
template <class Assignable>
void swap(Assignable& a, Assignable& b);
....
It may be possible that other libs have more specialized swaps for
pointers. If this is the case (IMO), you should get ambiguities.
>
> Foo foo1, foo2;
> swap(foo1, foo2);
void swap(Foo &, Foo &), for the same reason - non-templates preferred.
>
> Foo *foo_ptr1, *foo_ptr2;
> swap(foo_ptr1, foo_ptr2);
Once again, your template version is more specialized.
> }
>
> To my surprise, MSVC++ 8.0 prefers to call std::swap for int and int*.
This is surprising IMhO, and would like someone to educate me too in
the event of me being wrong

. I don't consider the compilers std
compliant, but I may be wrong.
Kind regards,
Werner