首页 > 解决方案 > c++ 中的函数重载如何在没有 Diamond 继承的情况下工作?

问题描述

在下面的示例中,

void f(double, double);  // at global scope

struct Grandparent {
    void f(int);
    void f(double, double);
};

struct Parent : public Grandparent {
    void f(int);  // hides all overloads of Grandparent::f
};

struct Child : public Parent {
    void g() { f(2.14, 3.17); }  // resolves to Parent::f
};

Parent::f 的声明如何支配和隐藏所有更祖先的声明而不考虑签名,也就是说,即使两个成员函数具有非常不同的签名,也Parent::f(int)支配和隐藏的声明?Grandparent::f(double, double)

我通过https://en.wikipedia.org/wiki/Dominance_(C%2B%2B)遇到了这个例子

标签: c++name-lookup

解决方案


因为隐藏的是名字;不涉及签名。根据名称查找规则,

名称查找如下所述检查范围,直到找到至少一个任何类型的声明,此时查找停止并且不再检查范围。

对于这种情况,当名称f在范围内找到时,Parent名称查找将停止;Grandparent根本不会考虑其中的名称。(顺便说一句:名称查找后,将检查重载解析签名以选择最佳匹配项)

如果这不是您期望的行为,您可以通过using.

struct Parent : public Grandparent {
    using Grandparent::f;
    void f(int);
};

struct Child : public Parent {
    void g() { f(2.14, 3.17); }  // refer to Grandparent::f(double, double)
};

推荐阅读