CRTP -- 访问不完整的类型成员
CRTP -- accessing incomplete type members
相关问题:one, two
CRTP弄了好几天,好像比以前懂的还少:)
考虑以下代码:
01 #include <iostream>
02
03 template <class IMPL>
04 class Interace
05 {
06 public:
07 typedef typename IMPL::TYPE TYPE; // ERROR: "...invalid use of incomplete type..."
08 void foo() { IMPL::impl(); } // then why does this work?
09 };
10
11 class Implementation : public Interface<Implementation>
12 {
13 public:
14 typedef int TYPE;
15 static void impl() { std::cout << "impl() " << std::endl; }
16 };
17
18
19 int main()
20 {
21 Implementation obj;
22 obj.foo();
23 }
问题是:
为什么我可以从 IMPL::
(第 8 行)调用函数但不能访问类型字段(第 7 行)?在相关问题中,据说 IMPL
此时是不完整的类型。但是为什么第 8 行是正确的呢?
输入declaration/definition的顺序是什么?如我所见:
一个。 Interface
模板 -- 好的。在实例化之前不会带来任何问题
b。第 11 行 -- 在 class Implementation
之后 -- Implementation
声明但未定义的类型。
c。第 11 行——在 Interface<Implementation>
之后——模板实例化。由于步骤 (b),此时 Implementation
是已知的(但未定义!)。编译器 "injects" 代码用 IMPL
替换为 Implementation
。在这里,以我的观点,第 7 行和第 8 行都不合法,因为在这一点上,编译器不知道 Implementation
有这些成员。它是怎么知道的?
或者实例化真的在第 21 行?但在那种情况下,为什么第 07 行不起作用?
我考虑得更多,对我所拥有的 C++ 类型基础知识的了解更少。任何澄清表示赞赏。
当一个class模板被实例化时,除了非虚拟成员函数之外的它的成员也被一起实例化。然而,非虚拟成员函数仅在使用 odr 时实例化(基本上,调用或获取其地址)。
当编译器遇到class Implementation : public Interface<Implementation>
时,需要实例化Interface<Implementation>
。此时,Implementation
仍然是一个不完整的类型,它的 TYPE
成员还没有出现。另一方面,Interface<Implementation>::foo
仅在稍后在 main
中调用时实例化。到那时,Implementation
是一个完整的类型。
相关问题:one, two
CRTP弄了好几天,好像比以前懂的还少:)
考虑以下代码:
01 #include <iostream>
02
03 template <class IMPL>
04 class Interace
05 {
06 public:
07 typedef typename IMPL::TYPE TYPE; // ERROR: "...invalid use of incomplete type..."
08 void foo() { IMPL::impl(); } // then why does this work?
09 };
10
11 class Implementation : public Interface<Implementation>
12 {
13 public:
14 typedef int TYPE;
15 static void impl() { std::cout << "impl() " << std::endl; }
16 };
17
18
19 int main()
20 {
21 Implementation obj;
22 obj.foo();
23 }
问题是:
为什么我可以从
IMPL::
(第 8 行)调用函数但不能访问类型字段(第 7 行)?在相关问题中,据说IMPL
此时是不完整的类型。但是为什么第 8 行是正确的呢?输入declaration/definition的顺序是什么?如我所见:
一个。
Interface
模板 -- 好的。在实例化之前不会带来任何问题b。第 11 行 -- 在
class Implementation
之后 --Implementation
声明但未定义的类型。c。第 11 行——在
Interface<Implementation>
之后——模板实例化。由于步骤 (b),此时Implementation
是已知的(但未定义!)。编译器 "injects" 代码用IMPL
替换为Implementation
。在这里,以我的观点,第 7 行和第 8 行都不合法,因为在这一点上,编译器不知道Implementation
有这些成员。它是怎么知道的?
或者实例化真的在第 21 行?但在那种情况下,为什么第 07 行不起作用?
我考虑得更多,对我所拥有的 C++ 类型基础知识的了解更少。任何澄清表示赞赏。
当一个class模板被实例化时,除了非虚拟成员函数之外的它的成员也被一起实例化。然而,非虚拟成员函数仅在使用 odr 时实例化(基本上,调用或获取其地址)。
当编译器遇到class Implementation : public Interface<Implementation>
时,需要实例化Interface<Implementation>
。此时,Implementation
仍然是一个不完整的类型,它的 TYPE
成员还没有出现。另一方面,Interface<Implementation>::foo
仅在稍后在 main
中调用时实例化。到那时,Implementation
是一个完整的类型。