Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板类中的循环依赖_C++_Templates_Polymorphism - Fatal编程技术网

C++ 模板类中的循环依赖

C++ 模板类中的循环依赖,c++,templates,polymorphism,C++,Templates,Polymorphism,我将循环依赖项简化为以下内容: // Bar.h struct Bar {}; // Base.h #include "Foo.h" struct Bar; struct Base { void func(std::shared_ptr<Foo<Bar>> foobar); // use methods of Foo in some way. }; // Derived.h #include "Base.h" struct Derived : public B

我将循环依赖项简化为以下内容:

// Bar.h
struct Bar {};

// Base.h
#include "Foo.h"
struct Bar;
struct Base {
    void func(std::shared_ptr<Foo<Bar>> foobar); // use methods of Foo in some way.
};

// Derived.h
#include "Base.h"
struct Derived : public Base {};

// Foo.h
#include "Derived.h"
template <typename T>
struct Foo {
    void func(std::shared_ptr<Derived> d) {
        // use methods of Derived in some way.
    }
};
//Bar.h
结构条{};
//Base.h
#包括“Foo.h”
结构杆;
结构基{
void func(std::shared_ptr foobar);//以某种方式使用Foo的方法。
};
//导出的.h
#包括“Base.h”
派生结构:公共基{};
//福安
#包括“派生的.h”
模板
结构Foo{
无效函数(标准::共享\u ptr d){
//使用以某种方式导出的方法。
}
};
我不能在
Base.h
中简单地转发declare
Foo
,因为它是一个模板类,不能在
Derived.h
中转发declare
Base
,因为多态性,也不能在
Foo.h
中转发declare
Derived
,因为
Foo::func
使用
Derived
的成员

我以前读过关于将模板实现从声明中分离出来的内容,但我不知道最佳实践,也不确定它在这种情况下是否有效。这两个,
派生的
Foo
在我的程序中被广泛使用


如何解决此依赖关系?

声明采用
std::shared\u ptr
的函数不需要
类型的完整定义,只需(向前)声明即可。这允许您避免使用派生.h(在Foo.h中)和/或Foo.h(在Base.h中)的
#include

在相互引用的类中启用内联函数:

标题A.h

struct B;
struct A { 
    void a() {}
    void f();
    std::shared_ptr<B> b;
};
#include "A.tcc"
标题B.h

struct A;
struct B { 
    void b() {}
    void f();
    std::shared_ptr<A> a;
};
#include "B.tcc"

请确保所有文件都有标题保护

为什么不能向前声明类模板?据我所知,我不能?我有一个沉重的假设,即模板必须存在于它所使用的每个翻译单元中,因此无法向前声明。这是一个无效的假设吗?“模板必须存在于它在“是”中使用的每个翻译单元中(如果您将“使用”替换为“实例化”)。因此,不能向前宣布“错误”<代码>模板结构Foo是一个格式良好的前瞻性声明。好吧,我们每天都会学到一些新东西。谢谢值得补充的是,即使类型是模板,您所说的也是正确的。这是我以前不理解的部分。@vmrob啊,这不是从你的问题中得到的。你可以在两个地方打破循环,只有一个地方需要前向声明模板类。为了使我的示例尽可能简洁,我犯了一个错误,只包含了
Foo::func
的原型。在这种情况下,整个定义都应该存在,这将阻止向前声明
派生的
。@vmrob否,可以稍后给出定义。只有声明才是避免循环的关键。
struct A;
struct B { 
    void b() {}
    void f();
    std::shared_ptr<A> a;
};
#include "B.tcc"
#include A.h
inline void B::f() { a->a(); }