用于固定类型集的显式实例化的单行代码
One-liner for explicit instantiation of fixed set of types
我有一套固定的A
、B
、C
和D
四种类型,还有大量的class和函数模板适用于这些类型。
为了减少编译时间,我想将这些模板的定义放入 .cpp 文件中,并为这组固定类型显式实例化模板。
然而,显式实例化引入了很多样板代码,我想减少这些代码。 是否有一种优雅的方法可以显式实例化函数和 class 一组固定类型的模板?
下面是一些代码来说明问题:
#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
的内容为
/* 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
拼写错误和类似错误被预处理器捕获。这适用于以最少的代码重复实例化多个 functions/classes:
#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
”。
我有一套固定的A
、B
、C
和D
四种类型,还有大量的class和函数模板适用于这些类型。
为了减少编译时间,我想将这些模板的定义放入 .cpp 文件中,并为这组固定类型显式实例化模板。 然而,显式实例化引入了很多样板代码,我想减少这些代码。 是否有一种优雅的方法可以显式实例化函数和 class 一组固定类型的模板?
下面是一些代码来说明问题:
#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
的内容为
/* 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
拼写错误和类似错误被预处理器捕获。这适用于以最少的代码重复实例化多个 functions/classes:
#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
”。