【发布时间】:2014-02-17 01:59:52
【问题描述】:
我目前正在实现与通用字符串相关的模板类,它可以做很多复杂的事情。为了优化编译时间,我考虑在翻译单元而不是头文件中实现功能,然后为 UTF-8、UTF-16 和 UTF-32 实例化类型。我试图弄清楚的瓶颈是,如果可以将模板类实例化为多个翻译单元,因为一组成员函数所做的是非常复杂的代码,将其分离成很有意义它是自己的翻译单元。
这是我正在尝试做的示例:
example.h
template <typename T>
class Example
{
public:
void test1();
void test2();
};
example_test1.cpp
template <typename T>
void Example::test1()
{
...
}
template class Example<uint8_t>;
template class Example<uint16_t>;
template class Example<uint32_t>;
example_test2.cpp
template <typename T>
void Example::test2()
{
...
}
template class Example<uint8_t>;
template class Example<uint16_t>;
template class Example<uint32_t>;
明显(和 hacky)的解决方案是创建包含 example_test1.cpp 和 example_test2.cpp 的迷你“统一构建”,但这样做有点便宜,而且只有一个翻译单元。不知道有没有更好的解决方案?
编辑:如果您的答案是“将其放在标题中”,请不要这样做。那没有帮助。这里的想法是通过从头文件中删除不需要的内容来优化编译时间。由于头文件中过度使用模板,我们的编译时间已经很长了。而且我不需要关于如何使用其他方式优化编译时间的提示。我知道如何使用预编译的标头等。如果我能得到与主题相关的答案。
【问题讨论】:
-
将成员函数定义拆分成单独的文件究竟有什么好处?而且您使用的术语也没有意义。您谈到将它们保存在单独的翻译单元中,但随后提到了一种可能的解决方案,即有一些预构建过程将它们全部包含在一个文件中。好了,现在您已经创建了一个翻译单元!我建议您停止思考,只需将所有定义放入同一个文件中即可。如果您的模板仅对这 3 种类型有用,则可以采用显式实例化路线。最后,考虑将
char16_t和char32_t用于UTF-16/32 -
Praetorian:我并没有想太多。该代码非常复杂,将其拆分为两个翻译单元使其更具可读性。我建议的解决方案很老套,是的,最终会得到一个翻译单元。这就是为什么我正在寻找更好的解决方案。而且我无法使用任何 C++11 的东西,因为它还没有被编译器很好地采用,所以我坚持使用 C++03(这也需要在 PC 以外的其他平台上工作)。还要提一下,在实际代码中我们不使用 uint8_t 等。我们有自己的核心库,提供良好的 unicode 支持。
-
我们只需要同意不同意这一点的必要性。如果可读性/可导航性是问题,也许你需要一个更好的编辑器。我不认为你所要求的是可能的。无论如何,严格来说,由于缺少外部模板,您的解决方案在 C++11 之前都不是很便携。
标签: c++ file templates split instantiation