Is Curiously Recurring Template Pattern Implementation Specific?
所以我读过这个:https://en.wikipedia.org/wiki/cur奇地重复使用模板模式
并了解奇怪的循环模板模式(CRTP)是如何工作的。但似乎这取决于编译器的实现,特别是编译器:
虽然我可以看到这个顺序如何允许编译,但我觉得它是一个利用编译器构造的过程,而不是标准所要求的编译器传递顺序。但我觉得一套同样合法的编译器传递应该是:
如果编译器使用这些过程,那么当CRTP试图计算子类型时,它将在步骤2失败。
所以我刚刚编写了这些编译器过程,但是有没有一个标准要求对编译器施加约束,使其在很大程度上遵循第一个过程的3个过程?或者,CRTP是否存在于一个灰色地带,知道编译器目前是如何实现的?
正如我所看到的那样,标准需要第一次通过建立对象大小,然后第二次通过编译方法。但是这第二遍wld必须愿意在父对象之前构建子对象方法,这看起来是向后的。
CRTP从未被定义或有条件地支持实现,IIRC在发明时是一个令人愉快的惊喜,从此被接受。
来自[阶级]
A class-name is inserted into the scope in which it is declared immediately after the class-name is seen. The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name.
其中,class name是要声明的类的名称。因此,类名称在BASE子句(即基列表)之前已经可见,但类只有在其完整定义之后才完整。
但是,允许模板使用不完整的类型作为其类型参数,来自[temp]
A template type argument may be an incomplete type.
注意,模板是完整的,即使它的类型参数不是。
1 2 3 4 5 6 7 8 | template<typename> struct S {}; struct U // U is visible after this line : S<U> // S<U> is a complete type { S<U> s; // well-formed }; // U is complete after this line |
实例化模板可以完成的原因是模板类型参数本身在模板中可能不完整,从而避免了循环逻辑
1 2 3 4 5 6 7 8 9 | template<typename T> struct A { T t; // ill-formed, incomplete type T in instantiation of A from below }; struct B : A // implicit instantiation of the specialization A { }; |
我们认为这种模式是有效的。编译器如何编译它是无关紧要的,如果它符合标准,它将编译该代码。
这是很明确的。正如注释中所指出的,即使是标准也会使用功能。
考虑它的方法是,只要编写
不,CRTP不是特定于实现的。它必须由任何符合标准的编译器支持。
用标准的话来证明这一点是一项相当艰巨的任务。如果有人带着参考答案来找我,我会删除这个答案(并在这里做评论以提醒我这样做)。
如过路人所说:
Strictly speaking, it works because the injected class name exists before the base clause
BASE子句是冒号后面的所有内容:
1 | class Derived : CRTP<Derived> |
作为弗兰?ois andrieux和underlined指出,我们可以间接证明标准要求CRTP工作,因为它定义了使用CRTP的