继承和嵌套名称的陷阱

Pitfalls of inheritence and nested names

我在项目中设计 C++ 对象继承树时遇到了一个特殊情况。我预计以下会失败:

struct A {
    protected:
    struct C { };
};

struct B: A { 
    struct C { };
};

但是,这编译得很好。这像覆盖吗?我可以看出这不是模棱两可的,因为它们可以指定为 A::CB::C,但是这在多态情况下如何起作用?它会调用指定类型的 C 还是实例类型的 C?同样,假设下面的代码有效并且 func 存在于 C:

的两个实现中
A x = B();
decltype(x)::C::func();

哪个 C 会调用它们的函数?更一般地说,它们是描述这些代码片段如何解析的资源吗?

这很好,因为您有两个不相关的 struct C:一个是 B::C,另一个是 B::A::CC 只是他们的快捷方式名称。

如果您在每个 C 中都定义了一个静态函数 f(),您将能够从结构外部调用它而不需要任何对象,如您的代码所示:

A a =  B();              // the type of a is A (B is sliced, by the way) 
decltype(a)::C::f();     // so this calls A::C::f() 

现在为了完整起见,这里有一个更完善的示例,表明在任何时候都没有歧义:

struct A {
   struct C { static void f() { cout << "A::C::f" <<endl; } };
};

struct B: A {
    C c1;            // the only C known here is A::C
    struct C { static void f() { cout << "B::C::f" <<endl; }}; // now B::C hides A::C
    C c2;            // so here the closest C known is B::C
    A::C c3;         // and here I can be explicit about the C I want
    using D=A::C;    // and here another way to be explicit:
    D c4; 
};

int main() {    
    B  b; 
    decltype(b.c1)::C::f();    // A
    decltype(b.c2)::C::f();    // B  
}

online demo