Re: Elegant way of making template arguments dependent on user input?
On Oct 10, 1:24 pm, Thomas Pajor <thomas.pa...@logn.de> wrote:
Erik Wikstr=F6m wrote:
> Templates are a compile-time construct. You can not use any information
> that is not known at compile-time when instantiating them.
>
I'm well aware of this, but I thought the compiler could use the limited
amount of available choices for each template argument to generate all
neccessary versions of the class and instanciate the correct one
depending on the user input.
Basically I was looking for a way to shorten code like this
if (input_choice_A == 1) {
if (input_choice_B == 1) {
some_class<firstA,firstB> instance();
// redundant code
} else {
some_class<firstA,secondB> instance();
// redundant code
}} else {
if (input_choice_B == 1) {
some_class<secondA,firstB> instance();
// redundant code
} else {
some_class<secondA,secondB> instance();
// redundant code
}
}
Of course, instead of inserting the redundant code each time, you could
write a templated function like this:
template<typename Atype, typename Btype>
void run(some_class<Atype, Btype> &instance) {
// Redundant code here only once
}
So it seems to be technically possible to make template values dependent
on user input. But - and this is what really concerns me - I'd need to
define each combination of template arguments manually, which is a LOT
in my case. It would be much shorter (and easier maintainable) if I
could define them in a way as illustrated here
if (input_choice_A == 1)
typedef firstA first_argument; // I know this won't be visible from
outside the if construct
else
typedef secondA first_argument;
if (input_choice_B == 1)
typedef firstB second_argument;
else
typedef secondB second_argument;
And then just instanciate the class with
some_class<first_argument, second_argument> instance();
The advantage of such a technique becomes more and more obvious the more
combinations for the template arguments there are.
Regards,
Thomas
You should check out boost::mpl (http://www.boost.org/libs/mpl/doc/
index.html). You could use it to statically configure typelists of
allowed types for template parameters A,B and C and write a template
metaprogram to do the heavy lifting of enumerating the possibilities
at compile time. You would need to combine this with a factory (see
Alexandresceu's Modern C++ Design for a nice implementation) in order
to retrieve the types by name and make use of the enumerated types.
The problem that you will run into (and that has been mentioned
already) is knowing what type to declare for the object returned by
your factory. From the perspective of the caller, in your case the
factory returns an object of an indeterminate templated type fetched
by name. You will need to use inheritance and provide an interface in
order to declare and manipulate these objects.
Note well that the time it takes for the compiler to enumerate the
template possibilities (by construction of your approach) is
factorially complex and will, almost certainly, not result in swift
compile times. It will scale horribly with the addition of new types.
rob.