Reputation: 154
I'm new to C++ and have got stuck with an implementation. So my problem is as below:
I have interface classes, where the only difference in the classes is the no. of parameters one of its function has.
For Example:
class foo3()
{
private:
function3(a,b,c) {}
};
class foo5()
{
private:
function5(a,b,c,d,e) {}
};
To generalize these and use them without knowing their inner functionality, I have created a template class fooN and used template specialization, thus based on template parameter(int N) I can choose correct class object and do some processing.
Now I have algorithm where I'm creating an object of fooN template
class algo {
public:
fooN<5> fooObj;
private:
}
Is it possible to dynamically assign this template parameter(5) at run-time, or is there a work-around?
Currently I'm using CMake to statically set the template parameter.
Upvotes: 0
Views: 1016
Reputation: 67743
Is it possible to dynamically assign this template parameter(5) at run-time
Absolutely not. All template instantiation happens at compile time.
or is there a work-around?
Maybe.
You can certainly instantiate fooN
for a bunch of different values, and choose between them at runtime. The simplest way is something like this
int algo(int n)
{
switch(n) {
case 3: return algoImpl<3>();
case 5: return algoImpl<5>();
default: return -1;
}
}
although you obviously need to get your parameters from somewhere. You can reasonably have each algoImpl<N>
take a (runtime) vector of argument values, convert it into a tuple, and use std::apply
to invoke your underlying function.
Currently I'm using CMake
Commiserations.
... to statically set the template parameter.
Eww. Storing bits of your type system in a build configuration file feels a bit hairy. What does your build system know about the correct value of N that your code doesn't?
Upvotes: 2
Reputation: 915
Unfortunately this is not possible. Template parameters need to be known at compile time
When the compiler encounters this call to a template function, it uses the template to automatically generate a function replacing each appearance of myType by the type passed as the actual template parameter (int in this case) and then calls it. This process is automatically performed by the compiler and is invisible to the programmer.
Meaning all the values the template can be used with need to be known at compile time.
What you can do is the following
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;
}
But as you want an arbitrary number N
, I assume this is not a solution that is feasible for you. You can try to add a preprocessor macro to generate the function for arbitrary values of N
, but honestly, I wouldn't do that. It will make you executables very large and add a lot of time to your compile time.
You can maybe find a solution that is similar to what you're trying to do with initializer lists. This would let you do something like
my_type Var = {1, 2, 3, 4, 5, 6, ..., N};
You can use such a list as the parameter of a function.
Hope that helped you with what you're trying to achieve!
Upvotes: 0