How is template function call ambiguity resolved?
I want to make a function conj
which will be applied only if the type of the argument is NOT std::complex<T>
. I could use enable_if
, but do I need to?
If I have the following:
namespace{
template<typename T>
T conj (T x) {
return x;
}
}
And we already have in std
template<typename T>
std::complex<T> conj开发者_如何学Python (std::complex<T> x);
Will a call to conj(z)
where z
is std::complex<double>
be resolved to the std version (since it is a 'better' match?)
Will a call to conj (z) where z is std::complex be resolved to the std version (since it is a 'better' match?)
Yes. That is called Argument Dependent-name Lookup. ADL in short, and is also known as Koenig lookup.
I want to make a function conj which will be applied only if the type of the argument is NOT std::complex. I could use enable_if, but do I need to?
Nothing much. Define it inside a namespace, say me
. And use qualified-name if the type of argument is not defined in the same namespace, or can use unqualified-name if the type of the argument is defined in the same namespace. In the latter case takes advantage of ADL. Here is an example:
#include <iostream>
#include <complex>
namespace me
{
template<typename T>
T conj (T x)
{
std::cout << "me::conj" << std::endl;
return x;
}
struct A{};
}
struct B{};
int main()
{
std::complex<int> z(1,1);
conj(z); //calls std::conj due to ADL
me::A a;
conj(a); //unqualified-name : calls me::conj due to ADL
me::conj(10); //qualified-name : ADL doesn't work with built-in types!
B b;
me::conj(b); //qualified-name : B is not defined in 'me' namespace.
return 0;
}
Demo : http://www.ideone.com/0HRXr
精彩评论