2009-11-21 128 views
4

我有一个工厂类,它需要使用连续的模板参数(它们是简单的整数)实例化几个模板。如何在不展开整个循环的情况下实例化这些模板函数?C++在循环中实例化模板

唯一能想到的就是使用boost预处理器。你能推荐别的东西,它不依赖于预处理器吗?

感谢

+6

你可以发表一些说明你想要的代码吗? *你如何*实例化模板? – 2009-11-21 08:49:31

回答

8

模板参数必须是编译时常量。目前没有编译器认为循环计数器变量是一个常量,即使它展开之后。这可能是因为在模板瞬时化期间必须知道常量,这在发生循环展开之前就已经发生了。

但是有可能构建一个“递归”模板,并将专业化作为结束条件。但即使如此,循环边界需要编译时间不变。

template<int i> 
class loop { 
    loop<i-1> x; 
} 

template<> 
class loop<1> { 
} 

loop<10> l; 

将创建一个从环< 10 10模板类>循环< 1>。

0

我不认为这是可能的运行时间,因为MyClass<1>MyClass<2>是绝对不同的类。

但我有一个想法:如果你知道所有可能的值,那么你可以在你的工厂类中编写一个switch并将这个整数作为参数传递给工厂。

+0

如果你使用开关方式,那么所有的类都将被实例化。没有办法只实例化一个等于'n'的东西(因为它的值在编译时是不知道的)。 – 2009-11-21 13:56:13

2

它可能可以使用Boost metaprogramming library完成。但是,如果你以前没有使用过它或者被用来做过多的模板编程,它可能不值得需要学习如何去做的工作量。

0

模板在编译时被实例化,而不是运行时,所以你不能在一个循环中实例化它们。

+0

你可以用编译器做循环/迭代。请参阅上面的@drhirsch答案。 – Macke 2009-11-21 13:54:48

+0

我同意drhirsch提供了一个解决方案,但它不是一个循环,而是一个递归,所以我的观点是立场。我试图强调的一点是模板在运行时没有实例化,这在某种程度上可以解释drhirsch的答案。 – Clifford 2009-11-22 08:48:40

2

谢谢你们。

赫希博士是最接近需要的,但最终的前任解决方案是最干净的。让我重申这个问题:需要一些模板是在编译时使用常量参数

f0 = f<0,0>(); 
f1 = f<0,1>(); 
... 
fk = f<m,n>(); 

为m的任何显著数量被实例化,和正展开模板创建使代码忙碌。使用升压预处理器我做了以下操作:


#include "boost/preprocessor/seq/for_each_product.hpp" 
#include "boost/preprocessor/seq/to_tuple.hpp" 


#define SEQ_MASK  (0x1)(0x3) 
#define SEQ_M   (1)(2) 
#define SEQ_N   (1)(2) 

#define INSTANCE(r, tparams) {          \ 
      Kernel kernel = Instance<BOOST_PP_SEQ_ENUM(tparams)>(); \ 
      kernels[kernel.key()] = kernel; } 

     BOOST_PP_SEQ_FOR_EACH_PRODUCT(INSTANCE, (SEQ_MASK)(SEQ_M)(SEQ_N)); 

预处理器运行后,它会产生所有定义的三个序列的组合。