我有一组固定的四种类型A
, B
, C
and D
,以及大量使用这些类型的类和函数模板。
为了减少编译时间,我想将这些模板的定义放入 .cpp 文件中,并显式实例化这组固定类型的模板。
然而,显式实例化引入了很多样板代码,我想减少这些代码。是否有一种优雅的方法来显式实例化一组固定类型的函数和类模板?
下面是一些代码来说明问题:
#include <iostream>
class A { public: int foo() const { return 0; } };
class B { public: int foo() const { return 1; } };
class C { public: int foo() const { return 2; } };
class D { public: int foo() const { return 3; } };
template<typename T>
class SomeClass {
/* could have a member variable of type A-D */
T m_t;
/* or several functions which take such a type */
void printFoo(const T& t){
std::cout << t.foo() << "\n";
}
};
/* normal explicit instantiation */
//template class SomeClass<A>;
//template class SomeClass<B>;
//template class SomeClass<C>;
//template class SomeClass<D>;
/* or something with macros, but hopefully better than this: */
#define INSTANTIATE_FOR_ALL_TYPES \
INSTANTIATE_WITH(A) \
INSTANTIATE_WITH(B) \
INSTANTIATE_WITH(C) \
INSTANTIATE_WITH(D)
/* if this here could be one line instead of three, then you found the answer */
#define INSTANTIATE_WITH(TYPE) template class SomeClass<TYPE>;
INSTANTIATE_FOR_ALL_TYPES
#undef INSTANTIATE_WITH
int main(){
return 0;
}
如果程序的设计不能确定类型不会改变,我就不会使用显式实例化。另外,我知道对于编译一次代码,编译时间不会受到显式实例化的影响。然而,当编写包含许多模板的测试并且经常进行重新编译时,效果非常明显。
如果有另一种选择可以缩短编译时间,我对此持开放态度。
目前,在有人找到更好的解决方案之前,以下方法已经足够有效:
#define INSTANTIATE_FOR_ALL_TYPES(TYPE) template class SomeClass<TYPE>;
#include "instantiator.hpp"
与内容instantiator.hpp
being
/* lack of a header guard is intentional */
INSTANTIATE_FOR_ALL_TYPES(A)
INSTANTIATE_FOR_ALL_TYPES(B)
INSTANTIATE_FOR_ALL_TYPES(C)
INSTANTIATE_FOR_ALL_TYPES(D)
#undef INSTANTIATE_FOR_ALL_TYPES
拼写错误和类似的错误会被预处理器捕获。这非常适合以最少的代码重复实例化多个函数/类:
#define INSTANTIATE_FOR_ALL_TYPES(TYPE) \
template class SomeClass<TYPE>; \
template class AnotherClass<TYPE>; \
template void foo( const TYPE& );
#include "instantiator.hpp"
如果有人能发现这种方法的问题,我欢迎提供反馈。但我更喜欢“这可能会在情况 y 下导致问题 x”而不是“宏是邪恶的”和“这不是你应该使用的方式”#include
".
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)