c++c++17operator-overloadingenable-ifis-same

Using std::enable_if to avoid ambiguous templated binary operator overloading


I want to use std::enable_if to avoid ambiguous overloaded operator*(T,U) (or redefinitions) from MyClass*otherT vs otherT*MyClass vs MyClassT*MyClassT.

Let's say MyClass declaration is:

template <typename T> class MyClassT { ... };

Then in global scope:

template <typename T, typename U>
MyClassT<T> operator*(const MyClassT<T>& t, const MyClassT<U>& u)
{
    //...
}

template <typename T, typename U, std::enable_if_t<!std::is_same_v<MyClassT<T>, U>,bool> = true >
MyClassT<T> operator*(const MyClassT<T>& t, const U& u)
{
    //...
}

template <typename T, typename U, std::enable_if_t<!std::is_same_v<MyClassT<U>, T>,bool> = true >
MyClassT<U> operator*(const T& t, const MyClassT<U>& u)
{
    //...
}

But, this code still can't find the overloaded operator for it:

MyClassT<double> a;
double b;
MyClassT<double> c = a * b; 

I need help, what's wrong?


Solution

  • You don't need to use enable_if and default argument here as shown below.

    template <typename T, typename U >
    MyClassT<T> operator*(const MyClassT<T>& t, const U& u)
    {
        //...
        return {};
    }
    
    template <typename T, typename U >
    MyClassT<U> operator*(const T& t, const MyClassT<U>& u)
    {
        //...
        return {};
    } 
    MyClassT<double> a;
    double b;
    MyClassT<double> c = a * b;  //works now
    MyClassT<double> k = b * a; //works  
    

    Working demo