Я взял следующий пример из http://en.cppreference.com/w/cpp/language/function_template#Function_template_overloading и clang (3.4), кажется, обрабатывает его просто отлично, а g++ (4.8.3) дает ошибку "неоднозначной перегрузки":
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 правильно печатает 1 (как и ожидалось в соответствии с cppreference), а g++ дает эту ошибку:
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
Неужели g++ действительно плохо себя ведет здесь?