c++ - 在运行时指定模板参数

标签 c++ templates

考虑以下模板类

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)
}

模板参数 P1P2P3 都在一个限制范围内,比如从 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/

相关文章:

c++ - 哪个控制结构的时间复杂度较低?

c++ - memcpy 模板变体中的错误

c++ - 为什么在 graph_traits<> 中使用模板化类型定义时 g++ 会报错?

c++ - 这是错误的警告吗?

c++ - 将 "pointer to pointer"传递给模板函数

C++,std::pair <T, shirt> 中的模板 T

c++ - 动态分配、默认构造函数和虚拟表

c++ - 派生类的模板参数推导

c# - 在没有 Visual Studio 的情况下暂停恢复 UWP 应用程序的应用程序或代码

c++ - OpenCv:翻译图像,将像素环绕边缘 (C++)