Re: template of unknown compile-time type
On Jul 15, 10:47 am, "josedaniel.garcia" <josedaniel.gar...@uc3m.es>
wrote:
Just a correction on my previous message:
class myBaseA {
/* A interface */
virtual void func1() = 0;
virtual void func2() = 0;
};
template <typename T>
class myClassA : public myBaseA {
/* declarations */
void func1();
void func2();
};
class myClassB {
/* here are some declarations */
/* Now I have a member of type myBaseA*/
myBaseA * pA;
void initA() {
if (cond1) pA = new myClass<T1>;
else if (cond2) pA = new myClass<T2>;
...
}
};
With this you can decide the concrete type of pA on run time. However,
you should have a common interface defined in the base class. For
specific needs you could dynamic_cast in some myClassB method.
This is the same type of approach taken by using the boost::variant<>
method I mentioned in my response, except that it encapsulates all
this logic for you and removes the restriction that everything should
derive from a common base class. So for example you can do this:
struct do_something_visitor : public boost::static_visitor<>
{
template<class Arg1, class Arg2, ...>
void operator()(class1& c1, const Arg1& arg1, const Arg2&
arg2, ...)
{
//arbitrary code to execute any sequence of operations on c1.
}
template<class Arg1, class Arg2, ...>
void operator()(class2& c2, const Arg1& arg1, const Arg2&
arg2, ...)
{
//arbitrary code to execute any sequence of operations on c2.
}
template<class Arg1, class Arg2, ...>
void operator()(class3& c3, const Arg1& arg1, const Arg2&
arg2, ...)
{
//arbitrary code to execute any sequence of operations on c2.
}
};
boost::variant<class1, class2, class3> myclass;
boost::apply_visitor(
boost::bind(
do_something_visitor(), //an instance of the visitor
_1, //Leave the first arg of operator()
alone
ref(arg1), //hardcode 2nd arg of the operator
() to 'arg1'
ref(arg2), //hardcode 3rd arg of the operator
() to 'arg2'
...),
myclass); //Perform the operation on myclass
variant.
The reason this is better than inheritance hierarchies is that
inheritance hierarchies introduce a very tight coupling into your
program. The tighest possible coupling that can exist in fact. If
you want to change the types of functionality they share in common,
you have to make a change that affects so much other code.
This way you don't touch the interface. class1, class2, and class3
can have arbitrary interfaces that share nothing in common. Instead,
you can just define different visitors that do whatever is needed to
fit the logical operation you want around the interfaces that each
individual class provides, in a totally typesafe manner. And most of
the surrounding mechanics (of which there is a significant amount) to
make this work behind the scenes gets compiled away anyway and the
generated code is the same as just doing a simple switch statement and
dispatching on the type of item that happens to be in the variant at
the time.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]