【问题标题】:typecast operator in private base私有库中的类型转换运算符
【发布时间】:2014-02-07 19:26:19
【问题描述】:

我在 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.5、gcc-4.8.1 和clang-3.3。令人困惑的是,我显然不能要求(bool)o,因为Base 是一个私人基地。

这是预期的行为吗?

【问题讨论】:

  • 在考虑访问控制之前发生过载解决。
  • 那么这是在 C++ 标准中指定的吗?还是编译器的选择?
  • 在标准中。

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


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多