我很确定我已经知道答案了,但值得一试。
假设我有一个类型列表:
template <typename ...Ts>
struct typelist{};
它包含一些对象:
struct foo{};
struct bar{};
struct quux{};
using objects = typelist<foo, bar, quux>;
现在我有了一个模板类(baz
),它可以接受这些对象中的任何一个,但是,由于代码库大小和编译时间的原因,我希望在一个cpp文件中实现我的模板方法。
在baz.cpp的底部我有:
template <> class baz<foo>;
template <> class baz<bar>;
template <> class baz<quux>;
问题是我有很多像baz
这样的类,它们所使用的对象列表也在不断变化。那么......我是否可以保留对象的单个类型列表,并在每个像baz
这样的对象的cpp文件中使用它来进行专门化?然后,我所要做的就是在我有一个新对象时更新我的类型列表,所有的对象文件都将重建。
6条答案
按热度按时间bbmckpt71#
template <> class baz<foo>;
行向前声明了一个专门化,而不是模板示例化,我认为这正是您想要的。我不认为有直接的方法可以做到这一点,你必须做一些元编程。你可以使用Boost.Preprocessor来生成所有需要的代码:
也许有一种方法可以做到这一点,而不需要预处理器,但这样做会对
baz
类型提出额外的要求,关键是要在必须示例化它的上下文中使用该类型,包括它的所有方法。nimxete22#
我敢肯定,如果不使用预处理器,这是不可能的。你可以从一个参数重构模板参数包,但你必须实际传递一个参数的示例,这似乎是次优的。其次,显式模板示例化不允许在块作用域(即在模板函数中),所以没有办法编写一个模板显式示例化另一个模板。
正如Nir所指出的,为什么不直接使用X Macro呢?
现在只要在类型列表更改时更新MY_FOREACH_TYPES即可。
gzszwxb43#
先做重要的事:显式类模板示例化的正确语法为
而不是
template <> class baz<foo>
,template <> class baz<foo>
是显式类模板专用化(前向声明)。一种可能是示例化如下所示的类
这将强制
baz<foo>
,baz<bar>
,baz<quux>
的隐式示例化。好吧,但是您想从typelist
创建它。typelist
是一个已经专门化的模板,在C++中无法从"typelist
的外部世界"通过typelist
中的模板参数进行迭代。另一种可能是使用宏,但即使在宏中,你也不能使用你原来的
typelist
。我可以得出结论,你的问题没有解决给定的typelist
。作为一个解决方案,如果可能的话,我会把模板示例化留在编译器上。在这种情况下,未使用的模板不会被示例化。编译速度慢是由于meta-programs are specified.
fnatzsnv4#
与普通预处理器一起使用的版本
8qgya5xd5#
这样就可以了,最终只使用一个(或没有)类型的类型列表的特殊化。
koaltpgm6#
如果你不能修改现有的类型列表(如https://stackoverflow.com/a/33084314/567292),但可以合理地确定它的长度不会改变,你仍然可以使用Boost.Preprocessor沿着Boost.MP11:
每当类型列表的长度改变时,宏
OBJECTS_SIZE
就需要调整,但希望这种情况不会太频繁,现代编译器应该能够告诉你值应该改变为什么,你甚至可以在构建系统中生成它,并在编译器命令行中传递它。