CRTP-访问不完整的类型成员 [英] CRTP -- accessing incomplete type members

查看:84
本文介绍了CRTP-访问不完整的类型成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相关问题:一个两个

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

After trying to understand CRTP for several days it seems that now I understand even less than before:)

考虑以下代码:

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 }

问题是:

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

  1. Why I can call function from IMPL:: (line 8) but cannot access type fileds (line 7)? In related question it is said that IMPL is an incomplete type at this point. But why then line 8 is correct?

类型声明/定义的顺序是什么?如我所见:

What it the order of type declaration/definition? As I see it:

a. Interface模板-确定.在实例化之前不会带来任何问题

a. Interface template -- OK. Doesn't bring any problems until instantiating

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

b. line 11 -- after class Implementation -- Implementation type declared but not defined.

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

c. line 11 -- after Interface<Implementation> -- template instantiation. At this point Implementation is already known (but not defined!) due to step (b). Compiler "injects" code with IMPL replaced with Implementation. Here, to my point of view, neither line 7, neither line 8 are not legal because at this point, compiler doesn't know that Implementation has these members. How does it knows than?

也许实例化确实在第21行?但是在那种情况下,为什么07行不起作用?

Or maybe Instantiation really goes at line 21? But in that case why line 07 doesn't work?

我想的更多,对我拥有的C ++类型基础知识的了解也较少.任何澄清表示赞赏.

More I think about it, less understanding of C++ type fundamentals I have. Any clarification is appreciated.

推荐答案

实例化类模板时,将实例化除非虚拟成员函数以外的成员.但是,非虚拟成员函数仅在使用时会实例化(基本上是调用或使用其地址).

When a class template is instantiated, its members other than non-virtual member functions are instantiated together with it. Non-virtual member functions, however, are only instantiated when odr-used (basically, called or have their address taken).

当编译器遇到class Implementation : public Interface<Implementation>时,它需要实例化Interface<Implementation>.此时,Implementation仍然是不完整的类型,尚未看到其TYPE成员.另一方面,Interface<Implementation>::foo仅在稍后在main中被调用时实例化.此时,Implementation是完整类型.

When the compiler encounters class Implementation : public Interface<Implementation>, it needs to instantiate Interface<Implementation>. At this point, Implementation is still an incomplete type, its TYPE member has not yet been seen. On the other hand, Interface<Implementation>::foo is only instantiated later, when it's called in main. At that point, Implementation is a complete type.

这篇关于CRTP-访问不完整的类型成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆