如何在C ++中声明/定义相互依赖的模板? [英] How to declare/define interdependent templates in C++?

查看:255
本文介绍了如何在C ++中声明/定义相互依赖的模板?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常在C ++中,当我需要类之间的相互依赖时,我在头文件中使用前向声明,然后在每个cpp文件中包含两个头文件。

Usually in C++ when I need interdependencies between classes, I use forward declarations in the header files and then include both header files in each cpp file.

然而这种方法使用模板时中断。因为模板必须完全在头文件中(不包括我将代码放入cpp并枚举模板类A< T>; 的每个支持的<$ c>的情况$ c> T - 这并不总是可行,例如当 T 是一个lambda时)。

However this approach breaks when working with templates. Because templates have to be entirely in the header files (not counting the case when I put the code into cpp and enumerate template class A<T>; for each supported T - this is not always feasible, e.g. when T is a lambda).

那么有没有办法在C ++中声明/定义相互依赖的模板?

So is there a way to declare/define interdependent templates in C++?

代码示例

template<typename T> struct B;
template<typename T> struct A {
  void RunA(B<T> *pB) {
    // need to do something to B here
  }
};

template<typename T> struct B {
  void RunB(A<T> *pA) {
    // need to do something to A here
  }
};

如果我开始做某事 B in RunA(),我想,我会得到一个缺少定义的错误,因为只有前向声明B才可用 RunA()已编译。

If I start doing something to B in RunA(), I think, I will get a "missing definition" error because only forward declaration of B is available by the time RunA() is compiled.

也许有一些技巧来组织头文件,例如通过将每个头分成类定义和方法定义文件,然后以某种奇特的方式包含它们。或者也许可以通过第三/第四课来完成某些事情。但我无法想象具体如何做到这一点。

Perhaps there is some trick to organize header files e.g. by splitting each header into class definition and method definition files, and then including them in some fancy way. Or maybe something can be done via a third/fourth class. But I can't imagine how specifically to do this.

C ++ 11/14/17都可以(具体来说,它是MSVC ++ 2017,工具集v141)。

C++11/14/17 are ok (specifically, it's MSVC++2017, toolset v141).

推荐答案

您可以使用细粒度标题:

You can utilize fine-grained headers:

//  A.forward.hpp
template<typename T> struct A;

//  A.decl.hpp
#include "A.forward.hpp"
#include "B.forward.hpp"

template<typename T> struct A
{
    void RunA(B<T> *pB);
};

//  A.impl.hpp
#include "A.decl.hpp"
#include "B.hpp"

template<typename T> void A< T >::
RunA(B<T> *pB)
{
    // need to do something to B here
}

//  A.hpp // this one should be included by code using A
#include "A.decl.hpp"
#include "A.impl.hpp"

//  B.forward.hpp
template<typename T> struct B;

//  B.decl.hpp
#include "B.forward.hpp"
#include "A.forward.hpp"

template<typename T> struct B
{
    void RunB(A<T> *pA);
};

//  B.impl.hpp
#include "B.decl.hpp"
#include "A.hpp"

template<typename T> void B< T >::
RunB(A<T> *pA)
{
    // need to do something to A here
}

//  B.hpp // this one should be included by code using B
#include "B.decl.hpp"
#include "B.impl.hpp"

显然所有这些标题还需要某种我在这里省略的标题保护。 重要提示 .impl.hpp 标题被视为内部标题,在 .forward时,外部代码永远不应使用标题。 hpp .decl.hpp .hpp 可以在任何地方使用。

Obviously all of these headers also need some sort of header guards that I omitted here. Important notice: .impl.hpp headers are considered internal and should never be used by the outside code while .forward.hpp, .decl.hpp and .hpp can be used anywhere.

这种方法确实引入了循环包含依赖项,但是这不会导致问题:通过包含头文件生成的代码结构可确保代码部分按以下顺序包含:forward声明,类定义,方法定义。

This approach does introduce circular include dependencies, however this does not lead to problems: code structure produced by inclusion of headers ensures that code parts are included in the following order: forward declarations, class definitions, methods definitions.

这篇关于如何在C ++中声明/定义相互依赖的模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆