c++ 是否保证将祖母基础 class 向下转换为孙子 class 就像奇怪的重复模板模式一样?

Does c++ guarantee down-casting grandmother base class to grand child class like curiously recurring template pattern?

我想知道 c++ 是否像奇怪的重复模板模式一样保证将祖母基数 class 向下转换为孙子 class。 以下代码在我的环境中运行良好。但是我不确定它是否有效 conditions/environments。 请告诉我你所知道的。 非常感谢。

PS。老实说,我不确定我询问堆栈溢出的方式是好是坏。如果您发现不好的地方,请告诉我。再次感谢。

#include <iostream>

template <typename GrandChild>
class GrandBase {
public:
    void print(void) {
        const GrandChild* grand_child = static_cast<const GrandChild*>(this);
        std::cout << "GrandChild::value = " << grand_child->grand_child_value << std::endl;
    }
};

template <typename Derived>
class BridgeClass : public GrandBase<Derived> {};

class GrandChild : public BridgeClass<GrandChild> {
public:
    GrandChild() = default;
    virtual ~GrandChild() = default;

    int grand_child_value = 17;
};

void test_down_casting_to_grand_base(void) {
    GrandChild a;
    a.print();
}

int main(int argc, char **argv) {
    test_down_casting_to_grand_base();
    return 0;
}

输出为

GrandChild::value = 17

鉴于您提供的代码,是的,标准要求允许这样做。只要正确使用 CRTP,标准就要求它可以工作。即使与其他 classes in-between.

但是请注意,基础 class 也可以访问中间 class 的任何 public 成员。当然,如果名称冲突,top-most class 会覆盖它。

另外,请注意,传递最派生的 class 和传递 第一个 派生的 class 之间存在概念上的差异。基础 class 只能(直接)访问您传入的 class。因此,如果您仅传入第一个派生 class,如果该派生本身使用 CRTP 及其派生 class,你的基地 class 不会知道的。而如果您传递派生程度最高的 class,它可以访问派生程度最高的一个以及其间的任何 public 接口。

你想使用哪种取决于你想要的效果。