1

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).

jcxz
  • 1,226
  • 2
  • 12
  • 25
  • 2
    Surprsingly, this is the second time today that this specific clang behavior is brought up: https://stackoverflow.com/questions/69761018/is-clang-wrongfully-reporting-ambiguity-when-mixing-member-and-non-member-binary –  Oct 29 '21 at 22:16
  • @Frank thanks for pointing me at that question. I made a follow up to confirm my understanding. Could you take a look ? (https://stackoverflow.com/questions/69775647/the-meaning-of-more-specialized-template-in-overload-resolution-rules) – jcxz Oct 29 '21 at 23:22

0 Answers0