如何打破定义嵌套模板类的头的循环依赖?

时间:2017-06-23 16:41:22

标签: c++ circular-dependency c++17

编辑:关联的人不会解决这种特殊情况,因为在我的情况下有嵌套类型。

让我们想象一下情况是这样的:

//foo.hpp
//include guards

template <typename T>
class foo
{
    class bar;
};

bar的代码太大了,所以我喜欢(不是我,但并不重要)到另一个文件。

所以,目前的情况是:

//foo.hpp
#include <bar.hpp>
//include guards

template <typename T>
class foo
{
     class bar;
};

//bar.hpp
#include <foo.hpp>
//include guards    

template <typename T>
class foo::bar
{
    //...
}

这肯定是循环依赖。但问题是编译器(clang和gcc)接受它。

我应该修理它还是没有什么可以解决的?如果是错误,我该如何解决?我应该将所有内容转储到一个文件中并将其称为一天吗?

实际上,bar是一个迭代器,我不想单独使用它。

那里有警卫,所以我猜这就是阻止它被多次包括的原因,但是循环依赖让我很担心。

1 个答案:

答案 0 :(得分:1)

嗯,首先,你不能在没有foo的情况下使用bar,当然......但是你想从foo的标题中获取它。那么这个怎么样:

foo.hpp:

//include guards

// no, we won't include bar.hpp here...

template <typename T>
class foo
{
    class bar;
};

// foo::bar is now predeclared

// and now we include bar:
#include "bar.hpp"

bar.hpp不打算直接包含在内,所以我们只留下foo:

//include guards    

// don't need it:
//#include "foo.hpp"


template <typename T>
class foo::bar
{
    //...
};

包括foo在内的任何人都会包括酒吧。为了更清楚地表示不打算直接包含条形,我建议将其移动到具有适当名称的不同文件夹,例如: G。 “私人”。

不幸的是,我们可能会在bar.hpp中失去对foo的IDE支持。实际上,我们可以简单地通过在bar.hpp中包含foo.hpp来恢复它。

但是为什么 - 那么我们又有一个循环包括???

嗯,是的,我们有,但圆圈坏了!请记住,在 foo的声明之后,bar.hpp包含在中!与普通圆形夹杂物相比,这是一个很大的不同。那么从编译器中看到会发生什么:

  • foo.hpp包含在某处,声明了foo,之后添加了的bar.hpp
  • 再次包含
  • foo.hpp,但是定义了包含警戒,圆圈被破坏。

从IDE看,反之亦然: * bar.hpp包括foo.hpp * foo.hpp再次包含bar.hpp,但已经定义了警卫。

所以我们很好......实际上,现在甚至可以包括bar.hpp,但仍然会得到foo。