在第一章「洞悉C++函数重载决议」中的1.2.1.1节,并没有讨论继承相关的类成员名称查找规则,本文对此进行补充,下一版本(打印版)也将合并到对应章节当中。
先来看第一种情况,Multiple Inheritance。
情形一:
1struct A {
2 void f() {}
3};
4
5struct B {
6 void f(int) {}
7};
8
9struct C : A, B {
10};
11
12
13int main() {
14 C c;
15 c.f(); // Error! ambiguous
16 c.f(5); // Error! ambiguous
17}
if the declaration sets of S(f,Bi) and S(f,C) differ, the merge is ambiguous. (11.8.6.2)
1struct A {
2 void f() {}
3};
4
5struct B {
6 // void f(int) {}
7};
8
9struct C : A, B {
10};
11
12int main() {
13 C c;
14 c.f(); // OK
15 // c.f(5); // Error! ambiguous
16}
1struct A {
2 void f() {}
3};
4
5struct B {
6 void f(int) {}
7};
8
9struct C : A, B {
10 using A::f;
11 using B::f;
12};
13
14int main() {
15 C c;
16 c.f(); // OK
17 c.f(5); // OK
18}
In the declaration set, using-declarations are replaced by the set of designated members that are not hidden or overridden by members of the derived class, and type declarations (including injected-class-names) are replaced by the types they designate. (11.8.3)
1struct A {
2 void f() {}
3};
4
5struct B {
6 void f(int) {}
7};
8
9struct C : A, B {};
10
11int main() {
12 C c;
13 c.A::f(); // OK
14 c.B::f(5); // OK
15}
1struct A { // S(f, A) = { { A::f }, { A } }
2 void f() {}
3};
4
5struct B { // S(f, B) = { { B:f }, { B } }
6 void f(int) {}
7};
8
9struct C : A, B {}; // S(f, C) = { { invalid }, { A in C, B in C } }
10struct D : public virtual C {}; // S(f, D) = S(f, C)
11struct E : public virtual C { // S(f, E) = { { E:f }, { E } }
12 void f(char) {}
13};
14struct F : D, E {}; // S(f, F) = S(f, E)
15
16int main() {
17 F f;
18 f.f('c'); // OK
19}
1struct A {
2 void f() {}
3};
4
5struct B {
6 void f(int) {}
7};
8
9struct C : A, B {
10 void f(char) {}
11};
12
13int main() {
14 C c;
15 // c.f(); // Error, no function take 0 arguments
16 c.f(5); // OK, call f(char)
17 c.f('c'); // OK, call f(char)
18}
1struct A {
2 void f() {} // Not considered
3};
4
5struct B : A {
6 void f(int) {}
7};
8
9struct C : B {};
10
11
12int main() {
13 C c;
14 c.f(5); // OK
15 // c.f(); // Error
16}
1struct A {
2 void f() {} // Not considered
3};
4
5struct B : A {
6 using A::f; // make every f from A available
7
8 void f(int) {}
9};
10
11struct C : B {
12};
13
14
15int main() {
16 C c;
17 c.f(5); // OK
18 c.f(); // OK
19}