Reputation: 1515
I took the following example from http://en.cppreference.com/w/cpp/language/function_template#Function_template_overloading and clang (3.4) seems to be handling it just fine, while g++ (4.8.3) gives an 'ambiguous overload' error:
struct A {};
template<class T> struct B {
template<class R> void operator*(R&){ cout << "1" << endl; } // #1
};
template<class T, class R> void operator*(T&, R&) { cout << "2" << endl;} // #2
int main() {
A a;
B<A> b;
b * a; //prints 1
}
clang correctly prints 1 (as expected according to cppreference), while g++ gives this error:
test_templates.cpp: In function ‘int main()’:
test_templates.cpp:13:5: error: ambiguous overload for ‘operator*’ (operand types are ‘B<A>’ and ‘A’)
b * a; //prints 1
^
test_templates.cpp:13:5: note: candidates are:
test_templates.cpp:7:26: note: void B<T>::operator*(R&) [with R = A; T = A]
template<class R> void operator*(R&){ cout << "1" << endl; } // #1
^
test_templates.cpp:9:33: note: void operator*(T&, R&) [with T = B<A>; R = A]
template<class T, class R> void operator*(T&, R&) { cout << "2" << endl;} // #2
Is g++ actually misbehaving here?
Upvotes: 10
Views: 613
Reputation: 8494
That call is ambiguos. GCC is right.
§13.5.2/1
Thus, for any binary operator @, x@y can be interpas either x.operator@(y) or operator@(x,y). If both forms of the operator function have been declthe rules in 13.3.1.2 determine which, if any, interpretation is used.
And in this case, we do have both the member and nonmember function. The built-in version is not included because the left hand operator has class type.
If you called the operator explicitly, there would be no ambiguity. However, when the call is done through an operator (thus implicitly) there is nothing which can distinguish between member and nonmember, therefore they're both viable functions which, in this case, leads to an ambiguous function call.
Previous versions of clang report it as ambiguous as well: http://goo.gl/OWsJUv
Upvotes: 0
Reputation: 16070
This example is taken from the standard (this is the draft for c++11).
14.5.6.2 Partial ordering of function templates paragraph 3 example:
struct A { };
template<class T> struct B {
template<class R> int operator*(R&); // #1
};
template<class T, class R> int operator*(T&, R&); // #2
// The declaration of B::operator* is transformed into the equivalent of
// template<class R> int operator*(B<A>&, R&); // #1a
int main() {
A a;
B<A> b;
b * a; // calls #1a
}
So, the standard itself pretty much say this is legal code. I could copy-paste rules, but one might as well click link and jump to the relevant place. My point is only to prove this is a proper compilable code as defined by the standard.
For what it's worth on my debian clang 3.5.0
compiled it right away, clang 3.4.2
had to be executed with -std=c++11
, g++ 4.9.1
reported ambiguity in all cases (I even tried 1y).
I am puzzled by clang
behaviour, though. I thought it might have been ambiguous in earlier versions of c++, the rule to disambiguate was added as a part of c++11 and g++
didn't keep up. But clang 3.5
compiles it even with -std=c++98
.
Upvotes: 10