自动将类定义与声明分离? [英] Automatically separate class definitions from declarations?

查看:210
本文介绍了自动将类定义与声明分离?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的库几乎完全由头文件中的模板化类和函数组成,如下所示:

I am using a library that consists almost entirely of templated classes and functions in header files, like this:

// foo.h
template<class T>
class Foo {
  Foo(){}
  void computeXYZ() { /* heavy code */ }
};
template<class T>
void processFoo(const Foo<T>& foo) { /* more heavy code */ }


$ b b

现在这是坏的,因为编译时间难以忍受每当我包括这些头文件之一(实际上我包括在我的每个编译单元中的许多)。

Now this is bad because compile times are unbearable whenever I include one of those header files (and actually I include many of them in each of my compilation units).

由于作为模板参数,我只使用一个或两个类型,我计划为每个库头文件只包含声明的文件,而不使用重编码,像这样:

Since as a template parameter I only use one or two types anyway I am planning to create, for each library header file, a file that contains only declarations, without the heavy code, like this:

// NEW: fwd-foo.h
template<class T>
class Foo {
  Foo();
  void computeXYZ();
};
template<class T>
void processFoo(const Foo<T>& foo);

然后一个文件创建了我需要的所有实例。该文件可以单独编译一次

And then one file that creates all the instantiations that I'll need. That file can be compiled separately once and for all:

// NEW: foo.cpp
#include "foo.h"
template class Foo<int>;
template class Foo<double>;
template void processFoo(const Foo<int>& foo);
template void processFoo(const Foo<double>& foo);

现在我可以只包括 fwd-foo.h 在我的代码和编译时间短。我将链接到 foo.o 在结尾。

Now I can just include fwd-foo.h in my code and have short compile times. I'll link against foo.o at the end.

当然,我的缺点是我必须创建这些新的 fwd-foo.h foo.cpp 文件。当然,这是一个维护问题:当一个新的库版本发布,我必须适应这个新版本。还有其他缺点吗?

The downside, of course, is that I have to create these new fwd-foo.h and foo.cpp files myself. And of course it's a maintenance problem: When a new library version is released I have to adapt them to that new version. Are there any other downsides?

我的主要问题是:

新文件,特别是 fwd-foo.h 自动 ?我必须这样做许多库头文件(也许20左右),一个自动的解决方案将是最好的,尤其是在一个新的库版本发布,我必须再次与新版本。是否有任何工具可用于此任务?

Is there any chance I can create these new files, especially fwd-foo.h, automatically from the original foo.h? I have to do this for many library header files (maybe 20 or so), and an automatic solution would be best especially in case a new library version is released and I have to do this again with the new version. Are any tools available for this task?

编辑

在这种情况下,新支持的 extern 关键字如何帮助我?

Additional question: How can the newly supported extern keyword help me in this case?

推荐答案

我们使用 lzz 将单个文件拆分为单独的标题和翻译单位。默认情况下,它通常将模板定义放入标头,但是,您可以指定不希望发生这种情况。

We use lzz which splits out a single file into a separate header and translation unit. By default, it would normally put the template definitions into the header too, however, you can specify that you don't want this to happen.

可能会使用它考虑以下因素:

To show you how you might use it consider the following:

// t.cc
#include "b.h"
#include "c.h"

template <typename T> 
class A {
  void foo () {
    C c;
    c.foo ();
    b.foo ();
  }
  B b;
}

取上述文件并复制到't.lzz'文件。根据需要将任何 #include 指令置于单独的$ hdr和$ src块中:

Take the above file and copy it to 't.lzz' file. Place any #include directives into separate $hdr and $src blocks as necessary:

// t.lzz
$hdr
#include "b.h"
$end

$src
#include "c.h"
$end

template <typename T> 
class A {
  void foo () {
    C c;
    c.foo ();
    b.foo ();
  }
  B b;
}



现在最后,在文件上运行lzz,指定它将模板定义放入源文件。您可以在源文件中使用 $ pragma 来执行此操作,也可以使用命令行选项-ts:

Now finally, run lzz over the file specifying that it places the template definitions into the source file. You can either do this using a $pragma in the source file, or you can use the command line option "-ts":

将导致生成以下文件:

// t.h
//

#ifndef LZZ_t_h
#define LZZ_t_h
#include "b.h"
#undef LZZ_INLINE
#ifdef LZZ_ENABLE_INLINE
#define LZZ_INLINE inline
#else
#define LZZ_INLINE       
#endif
template <typename T>
class A
{
  void foo ();
  B b;
};
#undef LZZ_INLINE
#endif

及:

// t.cpp
//

#include "t.h"
#include "c.h"
#define LZZ_INLINE inline
template <typename T>
void A <T>::foo ()
          {
    C c;
    c.foo ();
    b.foo ();
  }
#undef LZZ_INLINE

然后,您可以通过一些grep / sed命令删除LZZ帮助程序宏。

You can then run these through some grep/sed commands to remove the LZZ helper macros.

这篇关于自动将类定义与声明分离?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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