考虑以下模板类
class MyClassInterface {
public:
virtual double foo(double) = 0;
}
class MyClass<int P1, int P2, int P3>
: public MyClassInterface {
public:
double foo(double a) {
// complex computation dependent on P1, P2, P3
}
// more methods and fields (dependent on P1, P2, P3)
}
模板参数 P1
、P2
、P3
都在一个限制范围内,比如从 0
到某个固定的值 n
在编译时固定。
现在我想构建一个“工厂”方法,例如
MyClassInterface* Factor(int p1, int p2, int p3) {
return new MyClass<p1,p2,p3>(); // <- how to do this?
}
问题是在模板参数只在运行时知道的情况下,如何实现模板类的构造。对于具有非常大域(如 double )的模板参数,是否也可以这样做?另请考虑,如果可能的解决方案可扩展为使用更多模板参数。
最佳答案
您可以这样做:
MyClassInterface* Factor(int p1, int p2, int p3) {
if (p1 == 0 && p2 == 0 && p3 == 0)
return new MyClass<0,0,0>();
if (p1 == 0 && p2 == 0 && p3 == 1)
return new MyClass<0,0,1>();
etc;
}
请注意,这甚至不能远程缩放到浮点值。它仅缩放到已知的离散值列表。
我之前也用过这段代码来做一些模板自动生成:
#include <boost/preprocessor.hpp>
#define RANGE ((0)(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12))
#define MACRO(r, p) \
if (BOOST_PP_SEQ_ELEM(0, p) == var1 && BOOST_PP_SEQ_ELEM(1, p) == var2 && BOOST_PP_SEQ_ELEM(2, p) == var3 && BOOST_PP_SEQ_ELEM(3, p) == var4) \
actual_foo = foo<BOOST_PP_TUPLE_REM_CTOR(4, BOOST_PP_SEQ_TO_TUPLE(p))>;
BOOST_PP_SEQ_FOR_EACH_PRODUCT(MACRO, RANGE RANGE RANGE RANGE)
#undef MACRO
#undef RANGE
编译器生成如下所示的输出:
if (0 == var1 && 0 == var2 && 0 == var3 && 0 == var4) actual_foo = foo<0, 0, 0, 0>;
if (0 == var1 && 0 == var2 && 0 == var3 && 1 == var4) actual_foo = foo<0, 0, 0, 1>;
if (0 == var1 && 0 == var2 && 0 == var3 && 2 == var4) actual_foo = foo<0, 0, 0, 2>;
if (0 == var1 && 0 == var2 && 0 == var3 && 3 == var4) actual_foo = foo<0, 0, 0, 3>;
if (0 == var1 && 0 == var2 && 0 == var3 && 4 == var4) actual_foo = foo<0, 0, 0, 4>;
if (0 == var1 && 0 == var2 && 0 == var3 && 5 == var4) actual_foo = foo<0, 0, 0, 5>;
if (0 == var1 && 0 == var2 && 0 == var3 && 6 == var4) actual_foo = foo<0, 0, 0, 6>;
if (0 == var1 && 0 == var2 && 0 == var3 && 7 == var4) actual_foo = foo<0, 0, 0, 7>;
if (0 == var1 && 0 == var2 && 0 == var3 && 8 == var4) actual_foo = foo<0, 0, 0, 8>;
etc...
另外,请注意,使用此方法时,有 4 个变量,每个变量的范围超过 13 个值,您将导致编译器实例化此函数的 28561 个拷贝。如果您的 n 为 50,并且您仍然有 4 个选项,那么您将实例化 6250000 个函数。这可能会导致编译缓慢。
关于c++ - 在运行时指定模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2873802/