Supported Operations for Implicitly Defined User Conversion Operators

45 Views Asked by At

I'm currently learning how implicitly defined conversion operators (also known as user-defined conversions) work for a given class. In my particular case, I wanted to test out my class to be implicitly converted to the default integer type. Found below is my code snippet.

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

class A {
    public:
        A(int);
        operator int() const;
    protected:
        int value;
};

A::A(int input) : value(input) {
}

A::operator int() const {
    return this->value;
}

int main() {
    A foo = 1; 
    foo = foo + 1;          // no error
    foo = foo * 1;          // no error
    foo = foo / 1;          // no error
    cout << foo << endl;    // no error
    !foo;                   // no error
    &foo;                   // no error
    foo%1;                  // no error
    foo != 1;               // no error
    foo == 1;               // no error
    foo >= 1;               // no error
    foo <= 1;               // no error
    foo < 1;                // no error
    foo > 1;                // no error
    foo && 1;               // no error
    foo || 1;               // no error
    A *boo = &foo;          // no error
    *boo = 5;               // no error
    cin >> foo;             // error
    foo *= 2;               // error
    foo++;                  // error
    return 0;
}

As you can see, these operators provide no errors, but the >>, *=, and ++ yield errors; i.e. the object of class A is not implicitly converted for these operators. I noticed that it isn't converted for similar assignment operators. Can someone explain why this is the case, and what the supported operators are for implicit user conversions?

1

There are 1 best solutions below

1
On BEST ANSWER

These operators:

cin >> foo;  // >> endl is a bug     
foo *= 2;               
foo++;  

can only be called on an l-value. Your conversion operator returns a temporary int, which is not an l-value. Also, your operator is const qualified, which means it can only be called on const A instances.

You need to provide a conversion operator that returns an l-value like this:

class A {
    public:
        operator int&();
    // ...
};

A::operator int&() {
    return this->value;
}

Note that this operator can't be const if you want it to return a modifiable l-value.

Here's a demo.