I have the code below (simplified as much as I could), which fails to compile with clang (I went all the way back, 3.4.1. is the only version that compiles this code):
// ////////////////////////////////////////////////
// Vector 3
template <typename T>
struct TVector3
{
TVector3() { }
template <class U>
TVector3<T>& operator*=(const U ) { return *this; }
//template <class U>
//TVector3<T>& operator*=(const TVector3<U>& ) { return *this; }
};
// ////////////////////////////////////////////////
// Matrix 3x3
template <typename T>
struct TMatrix3
{
TMatrix3() { }
};
template <typename T>
TVector3<T>& operator*=(TVector3<T>& v, const TMatrix3<T>& )
{
return v;
}
// ////////////////////////////////////////////////
int main()
{
TVector3<float> o;
TMatrix3<float> m;
o *= m; // the offending statement that triggers the compilation error
return 0;
}
On the other major compilers (gcc, MSVC, ICC) it compiles (https://godbolt.org/z/99nadcMM7).
What is going on here ?
As far as I can tell, the call should not be ambiguous and the matrix overload should be picked up based on the rule of the most specialized template function (according to this post: C++ templated function overloading rules).