减少模板标题的大小 我正在开发一个C++模板库,它可以很好地使用模板。对于大多数类,所有代码都驻留在一些.hpp文件中,该文件将由客户机代码直接包含。有两件事我很担心:
是否存在将实现代码移动到“后台”的设计模式?在设计非模板类时,我经常将“接口”类和实现类分开,前者将通过执行类似于减少模板标题的大小 我正在开发一个C++模板库,它可以很好地使用模板。对于大多数类,所有代码都驻留在一些.hpp文件中,该文件将由客户机代码直接包含。有两件事我很担心:,c++,templates,C++,Templates,是否存在将实现代码移动到“后台”的设计模式?在设计非模板类时,我经常将“接口”类和实现类分开,前者将通过执行类似于getImpl()->foo()的操作委托给后者,以便实现代码可以动态链接到。我不知道如何为模板执行此操作我认为动态链接可能对模板没有意义? 大模板标题(>1000行)是否常见?还是很糟糕?如果它坏了,我能用它做什么 我知道这个问题,但我认为我们问的是不同的事情:这个问题的关键是试图减小输出的大小,而我试图减小我的库标题本身的大小 更新:例如,如果您要设计std::vector,您将
getImpl()->foo()
的操作委托给后者,以便实现代码可以动态链接到。我不知道如何为模板执行此操作我认为动态链接可能对模板没有意义?
更新:例如,如果您要设计
std::vector
,您将如何组织其接口和实现(如果需要)?不要太担心标题大小。模板几乎总是将其所有代码都放在一个标题中,因为每个客户端都必须知道如何实例化类,以防它们创建一个全新的版本(使用不同的模板参数)
如果你担心1000行,看看向量。在VisualStudio2013中,它有3000行
话虽如此,您真的只需要到处可用的类声明和一次定义,就像任何普通类一样。因此,可以使用一个没有实现的模板头,然后使用实现创建一个.cpp。这个.cpp必须强制生成您在任何地方都需要的所有模板类型
在下面的示例中,B.cpp的作者必须知道将要使用的所有模板参数。您不需要这么多文件,但我认为这应该涵盖所有场景
B.h:
模板
结构B
{
B();
};
B_impl.h:
#include "B.h"
template<class T>
B<T>::B() {}
#包括“B.h”
模板
B::B(){}
B.cpp:
#include "B_impl.h"
template struct B<int>;
template struct B<short>;
#包括“B_impl.h”
模板结构B;
模板结构B;
main.cpp:
#include "B.h"
B<int> b;
#包括“B.h”
B B;
您的确切意思是缩小尺寸?为了避免由于应用的模板参数太多而导致代码实例化膨胀?@πάνταῥεῖ 我所说的尺寸主要是指代码行。向客户端公开千行标题对我来说是个坏主意(至少对于非模板代码而言)。如果您有不依赖于模板参数的非模板代码,请将其移出到单独的编译单元。@πάνταῥεῖ 如果我的库代码是仅模板代码,我假设您所说的仅适用于非模板客户机代码?“我假设您所说的仅适用于非模板客户机代码?”当然。因此,可以使用不带实现的模板标头,然后使用实现创建.cpp。这个.cpp必须强制生成您在任何地方都需要的所有模板类型。这是针对客户机代码或库代码的?我用完整的代码示例编辑了答案(我用模板替换了typedef,因为typedef没有实例化模板化的类)。对库代码执行此操作是非常危险的,因为您可能不知道客户机将使用库的每种类型。如果您要发布已编译的二进制文件,那么二进制文件也必须包含所有实例化。设想一个std::vector,在那里你不能使用你自己的类型。你可以在库中提供B.h和B_impl.h来避免这些问题,但我从来没有见过这样做。另外,假设B类有20个函数,main.cpp只使用其中一个。我认为编译器只需要编译1函数。但是,如果您如上所述使用模板结构B,编译器必须编译所有20个函数(链接器可能会删除其中19个)。
#include "B.h"
B<int> b;