为什么在以下代码中将类A的对象转换为bool(或int):
class A
{
public:
operator bool() const { return true; }
operator int() const { return 1; }
};
int main()
{
return A() == A();
}
Run Code Online (Sandbox Code Playgroud)
目前还不清楚他们转变成了什么?bool或int?
我们需要找到如何处理==.这将涉及寻找成员,非成员和内置候选人==.在这种情况下,我们没有任何成员/非成员候选人,因此这部分很容易.
内置候选人来自[over.built]/13(强调我的,并删节):
对于每对提升的算术类型 L和R,存在该形式的候选运算符函数
bool operator==(L, R);
在促进算术类型是升级后的整型和浮点类型.任何整体型小于int(包括bool)促进向int.(float 促进到double,但float仍然是一个"提升算术类型").对我们来说,这一点的重要部分实际上是"推广的算术类型"包括int但不包括bool.如此有效,我们有内置的候选人,如:
bool operator==(int, int);
bool operator==(int, long);
bool operator==(long, int);
bool operator==(long, long);
bool operator==(int, float);
// etc.
Run Code Online (Sandbox Code Playgroud)
这一组中有很多候选人.但我们基本上可以将它们分成两组.
第一组完全由以下部分组成:
bool operator==(int, int);
Run Code Online (Sandbox Code Playgroud)
这个候选人是可行的,我们有一个明确的最佳转换顺序,因为通过operator int() const比通过operator bool() const然后推广更好.
第二组由其他所有候选人组成.对于没有的每个提升的算术类型int,我们有两个等价的转换序列:一个通过bool转换,一个通过int转换.两者都不比另一个好.当我第一次写这个答案时,我认为这意味着这些候选人会被拒绝 - 但令人惊讶的是,正如TC所指出的那样:一个模糊的转换序列被等同于任何其他用户定义的转换序列.
因此,从第一组开始,我们有一个可行的候选者,其涉及用户定义的转换序列.从第二组开始,我们有很多具有模糊转换序列的候选者 - 这对于operator==(int, int)第一组中的候选人来说同样重要.
结果,A() == A()是不正确的.没有最好的可行候选人.gcc接受这个是错误的.
请注意,gcc确实拒绝了同样想法的非常类似的其他演示:
void check(int, int);
void check(float, float);
check(A(), A()); // gcc and clang reject, msvc accepts
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
150 次 |
| 最近记录: |