我有一个名为SmallInt
的类,它应该表示范围在0-255
之间(包括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';
}
}
让我关心的是:为什么我可以显式调用
operator int&
将值赋给smi
:smi.operator int&() = 33
,但不能隐式赋值:smi = 33;
?第一个表达式(
smi = 33;
)会报错,提示构造函数SmallInt(int)
使用了explicit
;我知道这一点,但我有一个返回可修改普通左值引用的转换运算符。因此换句话说,在这样的隐式赋值中为什么构造函数优先于转换运算符?
language-lawyer
标签。 - Eljay33
是int&&
类型,而不是int&
。 - Raildexint
的 prvalue。表达式不能具有引用类型。 - HolyBlackCatsmi = 33;
被解释为smi.operator=(33);
,这需要将33
转换为SmallInt
以便传递参数,并因此寻找合适的构造函数。 - Ruslan(int&) smi = 33;
,所以我猜它只尝试转换操作符=的右侧,这是有道理的,因为你不想转换要分配的值。 - laenNoCode