Consider the following code:
#include <iostream>
namespace ns1
{
struct A
{
};
template <class T>
std::ostream& operator << (std::ostream& os, const T& t)
{
return os << "ns1::print" << std::endl;
}
}
namespace ns2
{
template <class T>
std::ostream& operator << (std::ostream& os, const T& t)
{
return os << "ns2::print" << std::endl;
}
void f (const ns1::A& a)
{
std::cout << a;
}
}
int main()
{
ns1::A a;
ns2::f (a);
return 0;
}
Compilation fails with "ambiguous overload error" as per standard.
But why? Surely "equally good" operator in A's 'home' namespace should take precedence? Is there any logical reason not to do it?
It generates this error message when one overload is more specific for one argument's data type while another overload is more specific for another argument's data type.
The process of selecting the most appropriate overloaded function or operator is called overload resolution. Suppose that f is an overloaded function name. When you call the overloaded function f() , the compiler creates a set of candidate functions.
In Function overloading, sometimes a situation can occur when the compiler is unable to choose between two correctly overloaded functions. This situation is said to be ambiguous. Ambiguous statements are error-generating statements and the programs containing ambiguity will not compile.
When the compiler is unable to decide which function it should invoke first among the overloaded functions, this situation is known as function overloading ambiguity. The compiler does not run the program if it shows ambiguity error.
If you want the overload in namespace A
to be preferred than you'll have to add something to it to make it actually better. Say, by making it not a template:
namespace ns1
{
std::ostream& operator<<(std::ostream&, const A& );
}
Otherwise, there's really no conceptual reason to see why a function template in one namespace would be preferred to a function template in another namespace if both are exactly equivalent. After all, why would the function template in A
's namespace be "better" than the function template in f
's namespace? Wouldn't the implementer of f
"know better"? Relying solely upon function signature sidesteps this issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With