I have this class SmallInt
that should represent a positive integer value in the range 0-255
-inclusive:
struct SmallInt{
explicit SmallInt(int x = 0) : iVal_( !(x < 0 || x > 255) ? x :
throw std::runtime_error(std::to_string(x) + ": value outbounds!")){}
operator int&() { return iVal_; }
int iVal_;
};
int main(){
try{
SmallInt smi(7);
cout << smi << '\n';
cout << smi + 5 << '\n'; // 7 + 5 = 12
cout << smi + 5.88 << '\n'; // 7.0 + 5.88 = 12.88
smi = 33; // error: constructor is explicit
smi.operator int&() = 33;
cout << smi << '\n';
}
catch(std::runtime_error const& re){
std::cout << re.what() << '\n';
}
}
What matters me is: why can I assign to
smi
explicitly callingoperator int&
:smi.operator int&() = 33
but not implicitly:smi = 33;
?The first expression (
smi = 33;
) complains about the constructorSmallInt(int)
beginexplicit
; I know that but I have the conversion operator that returns a modifiable plain lvalue. So in other words why in such an implicit assignment is the constructor preferred to the conversion operator?
Thus
(int &)smi = 33
interpretation is explicitly prohibited from consideration by the standard.