【问题标题】:Overload resolution over several layers of inheritance?多层继承的重载解决方案?
【发布时间】:2018-03-01 02:49:27
【问题描述】:

考虑以下具有多个继承层的示例:

struct A {
    void operator()(double x);
};

struct B: A {
    using A::operator();
    template <class... T> void operator()(T... x);
};

struct C: B {
    using B::operator();
    void operator()() const;
    void operator()(int x) const;
};

struct D: C {
    using C::operator();
    void operator()();
};

重载解析是否会像 D 被写成一样工作:

struct D {
    void operator()(double x);
    template <class... T> void operator()(T... x);
    void operator()() const;
    void operator()(int x) const;
    void operator()();
};

或者相反,编译器尝试在D,然后在C,然后在B,然后在A 中找到工作重载?换句话说,继承在重载解析中是否起任何作用(对于没有相同签名的函数)?

【问题讨论】:

  • 不鼓励以使现有答案不正确的方式编辑问题。
  • 重载根据定义有不同的签名。

标签: c++ inheritance standards c++17 overload-resolution


【解决方案1】:

一般规则是重载决议将考虑通过名称查找找到的声明集,而不考虑其他声明。

根据[namespace.udecl]/1:

using-declaration 中的每个 using-declarator 都将一组声明引入到 using-declaration 出现。 using-declarator 引入的声明集可通过以下方式找到 对 usingdeclarator 中的名称执行限定名称查找(6.4.3、13.2),不包括以下函数 如下所述被隐藏。

因此,operator()D 范围内的名称查找,即找到D::operator() 以及using-declaration,必须在范围内递归查找operator()C,它找到两个C::operator()s 以及using-declaration,等等。所以是的,在您的情况下,重载解决方案会将operator()s 的全部集合视为候选对象。

【讨论】:

    【解决方案2】:

    D::operator() 隐藏父级的重载。

    您必须使用C::operator() 编写(其他基础也一样)。

    然后所有的重载都是可见的。

    【讨论】:

    • void operator()() 和 void operator()() 不是不同的签名吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 1970-01-01
    • 2012-08-14
    • 2017-12-30
    • 1970-01-01
    • 2012-11-15
    • 2023-04-08
    相关资源
    最近更新 更多