私有基地的类型转换运营商

时间:2014-02-07 19:26:19

标签: c++ implicit-conversion overload-resolution private-inheritance member-access

我在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私人基础。

这是预期的行为吗?

1 个答案:

答案 0 :(得分:2)

访问控制始终是最后的。从标准引用:

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

  

1会员名称查找确定名称的含义(id-expression)   在一个范围内(3.3.7)。名称查找可能导致歧义   在哪种情况下,该计划是不正确的。对于id-expression,名称   查询从此类的范围开始;对于限定ID,名称   查询从nestedname-specifier的范围开始。 名称查找   在访问控制之前进行(3.4,第11条)。

     

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

考虑两个运算符的原因是:a)基类转换不会被派生的转换(如果两者都转换为相同的类型,它会被隐藏),b)bool和{{ 1}}可写入stdout,c)两者都不是比另一种更好的匹配,因此重载决策会产生歧义。即使在访问控制发挥作用之前,这也会产生硬错误。