为什么转换构造函数优于转换运算符?
Why is the converting constructor preferred to the conversion operator?
我有这个 class 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
;我知道,但我有转换运算符 returns 一个可修改的普通左值。那么换句话说,为什么在这样的隐式赋值中构造函数优先于转换运算符?
[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.
因此,(int &)smi = 33
标准明确禁止考虑解释。
我有这个 class 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)
beginexplicit
;我知道,但我有转换运算符 returns 一个可修改的普通左值。那么换句话说,为什么在这样的隐式赋值中构造函数优先于转换运算符?
[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.
因此,(int &)smi = 33
标准明确禁止考虑解释。