自动将类定义与声明分离? [英] Automatically separate class definitions from declarations?
问题描述
我使用的图书馆几乎完全由头文件中的模板化类和函数组成,
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屋!