c++ - Curiously Recurring Template Pattern 的实现是特定的吗?

标签 c++ metaprogramming language-lawyer crtp

所以我通读了这个:https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

并了解 Curiously Recurring Template Pattern (CRTP) 的工作原理。但它似乎取决于编译器的实现,特别是编译器:

  1. 定义每个模板类所需的空间
  2. 然后编译子类的方法
  3. 然后编译父类的方法

虽然我可以看到此顺序如何允许编译,但我觉得这是一种利用编译器构造,而不是标准要求的编译器传递顺序。但我觉得一组同样合法的编译器传递将是:

  1. 定义父类需要的空间
  2. 编译父类方法
  3. 定义子类所需的空间
  4. 编译子类方法

如果编译器使用这些传递,CRTP 在尝试评估子类型时将在第 2 步失败。

所以我刚刚编写了这些编译器传递,但是是否有标准要求对编译器施加约束,使其非常遵守 1st 的 3 次传递?或者 CRTP 是否存在于了解当前编译器如何实现的灰色地带?


正如我所看到的那样,该标准需要要求第 1st 遍确定对象大小,然后是第 2nd 遍编译方法。但是这第 2nd 遍必须愿意在父对象之前构建子对象方法,这似乎是倒退的。

最佳答案

CRTP 从来没有实现定义或有条件地支持,IIRC 在发明时它是一个惊喜,并且从那时起就被接受了。

来自 [class]

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 是被声明的类的名称。因此,class-namebase-clause 之前已经可见,它是基的列表,但类只有在其完整定义之后才完整。

但是,模板允许使用不完整的类型作为其类型参数,来自 [temp]

A template type argument may be an incomplete type.

请注意,即使其类型参数不完整,模板也是完整的。

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

实例化的模板之所以可以完整是因为模板类型参数本身在模板中可能是不完整的,从而避免了循环逻辑

template<typename T>
struct A
{
    T t;  // ill-formed, incomplete type T in instantiation of A<B> from below
};

struct B : A<B>  // implicit instantiation of the specialization A<B>
{
};

我们断定该模式是有效的。 编译器如何设法编译它是无关紧要的,如果它符合标准,它将编译该代码。

关于c++ - Curiously Recurring Template Pattern 的实现是特定的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47797105/

相关文章:

c++ - 静态检查 const char* 包含空格

c++ - 为什么允许嵌套类模板的部分特化,而不允许完全特化?

c++ - 规避类的构造函数是合法的还是会导致未定义的行为?

c++ - 在这种情况下,关键字 "typename"和 "template"都不需要吗?

c++ - 伪代码翻译

c++ - 如何从模板生成具有 const 或非常量成员函数的类?

c++ - 懒惰评估(短路)模板条件类型的通用方法

c++ - 使用 'using' 指令隐藏名字

c++ - 在二进制文件上使用 Getline

c++ std::unique_ptr 不会在 map 中编译