Reputation: 60491
Consider the following code
namespace std {
struct type1 {/* Definition */};
template <class T> constexpr T operator+(const type1& x1, const T& x);
template <class T> constexpr T operator+(const T& x, const type1& x1);
}
namespace other {
struct type2 {/* Definition */};
template <class T> constexpr T operator+(const type2& x2, const T& x);
template <class T> constexpr T operator+(const T& x, const type2& x2);
}
int main(int argc, char** argv)
{
std::type1 var1;
other::type2 var2;
auto x = var1 + var2; // What will happen here?
}
What would happen on the line auto x = var1 + var2
?
Is that a defined behaviour or not?
And does that mean that the standard library would never define generic operators with a template on only one side to avoid conflicting use?
Upvotes: 3
Views: 204
Reputation: 42939
According depended name look up (a.k.a Koenig Lookup) rules which are well defined. The compiler will lookup function names in the namespaces of the operator+
arguments in addition to the scopes and namespaces considered by the usual unqualified name lookup.
Thus, the compiler is going to add to the overload set both the matching overloaded operators (i.e., from namespaces std
and other
).
Consequently, you'll get an ambiguous call error.
Upvotes: 4
Reputation: 4835
You should get an ambiguous operator error on conforming compilers. Your program is ill formed since both versions of overload qualify as candidates.
Upvotes: 1
Reputation: 141633
This code causes undefined behaviour. It is not permitted to add your own things to namespace std;
, other than explicit specializations of existing templates.
Upvotes: -1