mercredi 21 janvier 2015

why is overload preferred to explicit specialization in ADL

Consider the code:



#include <iostream>
#include <algorithm> // std::swap C++98
#include <utility> // std::swap C++11

namespace A
{
template<typename T>
struct Foo {};

template<typename T>
void swap(Foo<T> &lhs, Foo<T> &rhs)
{
std::cout << "A::swap<T>" << std::endl;
}

} /* end namespace A */

namespace std // we explicitly specialize std::swap here
{

template<> // explicit template specialization for std::swap<int>
void swap(A::Foo<int> &lhs, A::Foo<int> &rhs)
noexcept
(is_nothrow_move_constructible<A::Foo<int>>::value && is_nothrow_move_assignable<A::Foo<int>>::value)
{
std::cout << "std::swap<int>" << std::endl;
}

} /* end namespace std */

int main()
{
using std::swap;
A::Foo<int> a, b;
A::Foo<double> x, y;

swap(a, b); // ADL, expected to call std::swap<Foo<int>>, but NO
swap(x, y); // ADL, expected to call A::swap<T>, YES
}


I would expect the std::swap explicit specialization to be a better candidate in the call swap(a, b), however it seems that the overload A::swap is always preferred, i.e. the output is:




A::swap<T>
A::swap<T>


Can anyone explain why this behaviour?


Aucun commentaire:

Enregistrer un commentaire