1

我在 C++ 中发现了一些我认为奇怪的行为:私有基类中的类型转换运算符在尝试解析隐式转换时使编译器感到困惑:

#include <iostream>
struct Base
{
#ifdef ENABLE
    operator bool () const { return true; }
#endif
};
struct Derived : private Base
{
    operator int () const { return 7; }
};
int main()
{
    Derived o;
    std::cout << o << '\n';
    return 0;
}

没有-DENABLE,代码编译得很好,并输出7. 使用-DENABLE,代码不再编译,抱怨一个模棱两可的重载。我试过了gcc-4.6.5gcc-4.8.1clang-3.3。令人困惑的是,我显然不能要求(bool)o,因为Base私人基地。

这是预期的行为吗?

4

1 回答 1

2

访问控制总是最后。引用标准:

10.2 成员名称查找[class.member.lookup]

1 成员名称查找确定类范围(3.3.7)中名称(id-expression)的含义。名称查找可能会导致歧义,在这种情况下程序格式错误。对于 id 表达式,名称查找从 this 的类范围开始;对于qualified-id,名称查找在nestedname-specifier 的范围内开始。名称查找发生在访问控制之前(3.4,第 11 条)。

8 如果明确找到重载函数的名称,则 重载决议(13.3)也发生在访问控制之前。 歧义通常可以通过使用类名限定名称来解决。

考虑这两个运算符的原因是 a) 派生类不会隐藏基类转换(如果两者都已转换为相同类型,则会隐藏),b) 两者boolint可以写入标准输出,c) 两者都不是比另一个更好的匹配,因此重载解决方案会产生歧义。即使在访问控制发挥作用之前,这也会产生一个硬错误。

于 2014-02-07T20:51:29.240 回答