Re: is it possible to create the functionality of a virtual template
method?
On 23 d=E9c, 11:04, "ted orange" <nos...@please.com> wrote:
"Michael Doubez" <michael.dou...@free.fr> wrote in message
news:7383d7f5-bc8f-446a-b6f3-ec139ff9f21b@r5g2000yqb.googlegroups.com...
On 23 d=E9c, 09:54, "ted orange" <nos...@please.com> wrote:
I would like to have a container of objects where each object has a
template
method like so
template <class T>
void DoSomething(T& t);
so that I may, at runtime, pass various types to that method. The type
will
be automatically dededuced.
I understand that virtual template methods are not permitted and that
containers may only store heterogeneous collections if they are
polymorphic.
Is there a mechanism by which I can attain my objective?
There are many ways with different trade-offs. It depends on the
contract you can make on T or on how much you can impact on the
objects.
Three examples:
[snip]
2 You can wrap T into a polymorphic object reflecting the contracts/
concepts on T and pass it to a virtual function. It comes at the cost
of reducing the range of type.
[snip]
Myself, I would favor the second solution because it provides high
control on the input types and keeps coupling low.
[snip]
I think I understand what you're saying but plz provide an example of 2 t=
o
clarify. Thanks.
I have posted an example not so long ago:
http://groups.google.fr/group/comp.lang.c++/browse_frm/thread/724c2ca96069a=
245/544fa4fb6b567799
Here is a copy of the relevant example:
<quote>
One approach is to use dynamic polymorphism, that is if you can
define a same contract on your type. As an example if your foo is only
displaying a message with the data in parameter, your contract if that
the type should support (ostream<<T), you define the interface:
struct foo_ostreamable
{
virtual ostream& output(ostream&)const=0;
};
Then you define a templated foo_streambable implementation:
template<typename T>
struct foo_ostreamable_imp: foo_ostreamable
{
T value;
foo_ostreamable_imp(const T& t):value(t){}
virtual ostream& output(ostream& os)const{return os<<value;}
};
And finally the parameter of SuperClass::foo with templated
constructor:
struct foo_param
{
template<typename T>
foo_param(const T& t){data.reset(new foo_ostreamable_imp<T>(t));
scoped_ptr<foo_ostreamable> data;
};
// foo_param can be written into ostream
ostream& operator<<(ostream& os,const foo_param& p)
{
return p.data->output(os);
}
And finally, you define your classes:
class SuperClass
{
public:
virtual void foo(const foo_param&) const = 0;
};
class SubClass: public SuperClass
{
public:
virtual void foo(const foo_param& p) const { cout << p <<
endl;}
} ;
The compiler will automatically resolve with correct subtype:
SubClass s;
s.foo(1);
s.foo(0.1);
s.foo("bar");
....
If you want to keep/compare foo_param values, there is some management
to do such as deep copy and others to put it into canonical form. If a
type doesn't react as you want, you overload foo_param constructor.
</quote>
--
Michael