Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
257 views
in Technique[技术] by (71.8m points)

c++ - Specify template parameters at runtime

Consider the following template class

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

The template parameters P1, P2, P3 are in a restricted range like from 0 to some fixed value n fixed at compile time.

Now I would like to build a "factory" method like

MyClassInterface* Factor(int p1, int p2, int p3) {
  return new MyClass<p1,p2,p3>(); // <- how to do this?
}

The question would be how to achieve the construction of the template class when template parameters are only known at runtime. And would the same be possible with template parameters having a very large domain (like a double)? Please consider also, if the possible solution is extendable to using more template parameters.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here's what you can do:

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

Note that this does not even remotely scale to floating point values. It scales only to a known list of discrete values.


I've also used this bit of code before to do some template automatic generation:

#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

The compiler produces output that looks like this:

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...

Also, please note that with this method, with 4 variables, each ranging over 13 values, You would cause the compiler to instantiate 28561 copies of this function. If your n was 50, and you still had 4 options, you would have 6250000 functions instantiated. This can make for a SLOW compile.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...