3

我有这个类SmallInt应该表示范围内的正整数值 - 包括0-255

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';
    }
}
  • 我重要的是:为什么我可以指定smi显式调用operator int&:smi.operator int&() = 33但不能隐式调用 : smi = 33;

  • 第一个表达式 ( smi = 33;) 抱怨构造函数SmallInt(int)begin explicit;我知道,但我有返回可修改的普通左值的转换运算符。那么换句话说,为什么在这样的隐式赋值中构造函数优于转换运算符?

4

1 回答 1

6

[over.match.oper]/4对于内置赋值运算符,左操作数的转换限制如下:
...
(4.2) — 不对左操作数应用用户定义的转换以实现类型匹配使用内置候选的最左侧参数。

因此(int &)smi = 33,标准明确禁止解释。

于 2021-10-17T13:42:28.767 回答