CRTP -- 访问不完整的类型成员

CRTP -- accessing incomplete type members

本文关键字:类型 成员 访问 CRTP      更新时间:2023-10-16

相关问题:一,二

在尝试了解CRTP几天后,现在我似乎比以前了解得更少:(

请考虑以下代码:

#include <iostream>
template <class IMPL>
class Interace
{
public:
    typedef typename IMPL::TYPE TYPE;  // ERROR: "...invalid use of incomplete type..."
    void foo() { IMPL::impl(); }       // then why does this work?
};
class Implementation : public Interface<Implementation>
{
public:
   typedef int TYPE;
   static void impl() { std::cout << "impl() " << std::endl; }
};
int main()
{
    Implementation obj;
    obj.foo();
}

问题是:

  1. 为什么我可以从IMPL::调用函数(第 8 行(但无法访问类型文件(第 7 行(?在相关问题中,据说IMPL在这一点上是一个不完整的类型。但是为什么第8行是正确的呢?

  2. 类型声明/定义的顺序是什么?在我看来:

一个。 Interface模板 -- 好的。在实例化之前不会带来任何问题

b. 第 11 行 -- 在 class Implementation 之后 -- Implementation已声明但未定义的类型。

C. 第 11 行 -- Interface<Implementation>之后 -- 模板实例化。此时,由于步骤(b(,Implementation已经知道(但未定义!(。编译器"注入"代码,IMPL替换为Implementation。在这里,在我看来,第 7 行和第 8 行都不合法,因为此时编译器不知道Implementation有这些成员。它怎么知道比?

或者也许实例化真的在第 21 行?但是在这种情况下,为什么 07 行不起作用?

我想得更多,对我所拥有的C++类型基本面的理解更少。任何澄清都值得赞赏。

实例化类模板时,非虚拟成员函数以外的其他成员将随之实例化。但是,非虚拟成员函数仅在使用 ODR 时实例化(基本上,调用或获取其地址(。

当编译器遇到class Implementation : public Interface<Implementation>时,需要实例化Interface<Implementation>。此时,Implementation仍然是一个不完整的类型,其TYPE成员尚未出现。另一方面,Interface<Implementation>::foo 只有在稍后在 main 中调用时才实例化。在这一点上,Implementation是一个完整的类型。