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