Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the converting constructor preferred to the conversion operator?

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 calling operator int&: smi.operator int&() = 33 but not implicitly: smi = 33;?

  • The first expression (smi = 33;) complains about the constructor SmallInt(int) begin explicit; 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?

like image 509
Itachi Uchiwa Avatar asked May 21 '26 15:05

Itachi Uchiwa


1 Answers

[over.match.oper]/4 For the built-in assignment operators, conversions of the left operand are restricted as follows:
...
(4.2) — no user-defined conversions are applied to the left operand to achieve a type match with the left-most parameter of a built-in candidate.

Thus (int &)smi = 33 interpretation is explicitly prohibited from consideration by the standard.

like image 91
Igor Tandetnik Avatar answered May 24 '26 07:05

Igor Tandetnik