Search code examples
c++typestype-conversionoperator-keywordmember

c++ type conversion class member operator issue


There are two simple classes:

class X
{
    int value;

public:

    X() : value(0) {};

    X(int v) : value(v) {};

    X(const X& x) {     // Does not help!
        this->value = x.value;
    }

    X(const X&& x) noexcept { // Does not help!
        this->value = x.value;
    }

    X& operator=(const X& right)  { // Does not help!
        this->value = right.value;
        return *this;
    };

    X&& operator=(const X&& right) noexcept  { // Does not help!
        this->value = right.value;
        return std::move(*this);
    };

    bool operator==(X& right) const {
        return this->value == right.value;
    };

};

class Y
{
    int value;

public:

    Y() : value(0) {};

    operator X() const {

        return X(this->value);

    };  // Y objects may be converted to X
};

And sample how I use it:

int main()
{

X x1, x2;
Y y1;

x1 = x2;   // Compiles (using the X& operator=)

x1 = std::move(x2);   // Compiles (using the X&& operator=)

auto newv = (X)y1; // Compiles 

x1 == newv;   // Accepted!

x1 == (X)y1;   // Error!!!

} // END: main()

x1 == (X)y1 line generates the error C2678: binary '==': no operator found which takes a left-hand operand of type 'X' (or there is no acceptable conversion)

and "no operator == matches these operands, operand types are X==X

I try to compile it with C++17.

Whats wrong with it if line like "x1 == newv" is good for the compiler?


Solution

  • bool operator==(X& right) const
    

    should be

    bool operator==(const X& right) const
    //               ^^
    

    otherwise it cannot be called with a temporary X, which (X)y1 is.

    https://ideone.com/tN1w8T

    Another problem, which is unrelated to your compiler error from my comment:
    bool operator=(X& left) const is this the comparison operator == or the assignment =? The function declaration is a mix and the implementation is clearly comparison. Assignment would be X& operator=(const X& left) {value = left.value; return *this;}.