简体   繁体   English

C++ 奇怪地重复出现的模板模式“使用未定义的结构”编译错误

[英]C++ Curiously Recurring Template Pattern “uses undefined struct” compile error

I have two classes using the Curiously Reoccurring Template Pattern with a parent class.我有两个类使用带有父 class 的奇怪重复出现的模板模式。

When I compile on VS2013 I get two errors, one for each subclass, stating:当我在 VS2013 上编译时,我得到两个错误,每个子类一个,说明:

'Parent<Child1>::_child' uses undefined struct 'Child1'
'Parent<Child2>::_child' uses undefined struct 'Child2'

Am I including the files incorrectly, or do I need to make some sort of forward declaration?我是否包含错误的文件,或者我需要进行某种前向声明?

Child1.h Child1.h

#include "Parent.h"

struct Child1 : public Parent<Child1>
{
    void init()
    {
        sharedCode();
    }
}; 

Child2.h Child2.h

#include "Parent.h"

struct Child2 : public Parent<Child2>
{
    void init()
    {
        sharedCode();
    }
}; 

Parent.h父母.h

template<class CHILD>
struct Parent
{
    void sharedCode()
    {
    }

    CHILD _child;
}; 

main.cpp主文件

#include "Child1.h"
#include "Child2.h"

int main()
{
    Child1 c1;
    Child2 c2;
}

When using the recurring template pattern, the child is an incomplete type in the scope of the parent.使用循环模板模式时,子代是父代的 scope 中的不完整类型。

template<class CHILD>
struct Parent
{
    CHILD _child; // <- there, incomplete
};

You cannot instantiate an incomplete type as its definition is not there yet.你不能实例化一个不完整的类型,因为它的定义还没有。

So... why is that?那么……这是为什么呢?

A type become complete when the compiler encounter the closing bracket:当编译器遇到右括号时,类型变得完整:

struct Hello {
    // Technically not complete yet
};
// Complete here, we encountered the closing bracket.

Also, parent classes are required to be complete type themselves:此外,父类本身必须是完整类型:

struct Incomplete;

struct NiceTry : Incomplete {}; // ERROR! `Incomplete` is an incomplete type.

So we have two rules here: the parent of a class must be complete, and a type is not complete until the closing bracket.所以我们这里有两条规则:class 的父级必须是完整的,并且类型在右括号之前是不完整的。 Inside the parent of a CRTP, we fail both condition: The parent is evaluated before the class scope (they are also positionned before the class scope in the code) and since the parent of a class must be complete, it must be complete before the child class is. Inside the parent of a CRTP, we fail both condition: The parent is evaluated before the class scope (they are also positionned before the class scope in the code) and since the parent of a class must be complete, it must be complete before the孩子 class 是。 You cannot have mutually complete types in class scope, no matter how hard you try:不管你怎么努力,在 class scope 中你不可能有相互完整的类型:

struct class2;

struct class1 {
    // Class 2 is incomplete here
};

struct class2 {
    // class1 complete
};

You cannot have both complete at the same time in both scopes.您不能在两个范围内同时完成两者。

The same thing happens with CRTP, there is no exceptions there. CRTP 也会发生同样的事情,那里没有例外。


Also, your code is roughly equivalent to this:此外,您的代码大致相当于:

struct class1 {
    class2 instance;
};

struct class2 {
    class1 instance;
};

If you try to compute the size of the types, you run into an infinite recursion.如果您尝试计算类型的大小,则会遇到无限递归。 You cannot have a type that contain itself.您不能拥有包含自身的类型。


To fix your problem, don't try to contain the child.为了解决你的问题,不要试图控制孩子。 Instead, since you know 100% which class is the child, simply cast this:相反,由于您 100% 知道 class 是孩子,因此只需转换:

template<typename Child>
struct parent {

    void common_behavior() {
        child().function1();
        std::cout << child().member1 + child().member2;
    }
    
private:
    auto child() noexcept -> Child& { return *static_cast<Child*>(this); }
    auto child() const noexcept -> Child const& { return *static_cast<Child const*>(this); }
};

And implement the child like that:并像这样实现孩子:

struct child1 : parent<child1> {
    void function1() { std::cout << "This is child 1"; }
    int member1, member2;
};

struct child2 : parent<child2> {
    void function1() { std::cout << "This is child 2"; }
    float member1, member2;
};

Live example活生生的例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C ++反复出现的模板模式,语法错误 - C++ Curiously recurring template pattern, syntax error “奇特重复出现的模板模式”的实际用途 - Practical Uses for the “Curiously Recurring Template Pattern” 奇怪的重复模板模式(CRTP),AutoLists和C ++ - Curiously Recurring Template Pattern (CRTP), AutoLists and C++ 如何在C ++中强制使用奇怪的重复模板模式 - How to force use of curiously recurring template pattern in C++ 奇怪的重复模板模式多态拷贝(C ++)中的继承 - Inheritance in curiously recurring template pattern polymorphic copy (C++) C ++ BigIntegers和奇怪的重复模板模式问题 - C++ BigIntegers and the Curiously Recurring Template Pattern Issue 具有可变参数模板的好奇重复模板模式(C ++) - Curiously recurring template pattern with variadic templates (C++) 我可以在这里使用 Curiously Recurring Template Pattern (C++) 吗? - Can I use the Curiously Recurring Template Pattern here (C++)? C ++:奇怪的重复模板模式是什么?并且可以奇怪地重复模板模式取代虚拟功能? - C++: what is the Curiously-Recurring-Template-Pattern? and can Curiously-Recurring-Template-Pattern replace virtual functions? 将关键字与奇怪重复的模板模式一起使用时出错 - Error with using keyword with curiously recurring template pattern
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM