generic programming and dynamic polymorphism

L

Leslaw Bieniasz

Cracow, 20.10.2004

Hello,

As far as I understand, the generic programming basically consists
in using templates for achieving a static polymorphism of the
various code fragments, and their reuse for various template
parameters. I wonder if there exist techniques for achieving
a dynamic polymorphism using the generic programming. Is this
possible? If yes, can anyone show me simple examples in C++
of how this can be done?

Sincerely,

L.B.


*-------------------------------------------------------------------*
| Dr. Leslaw Bieniasz, |
| Institute of Physical Chemistry of the Polish Academy of Sciences,|
| Department of Electrochemical Oxidation of Gaseous Fuels, |
| ul. Zagrody 13, 30-318 Cracow, Poland. |
| tel./fax: +48 (12) 266-03-41 |
| E-mail: (e-mail address removed) |
*-------------------------------------------------------------------*
| Interested in Computational Electrochemistry? |
| Visit my web site: http://www.cyf-kr.edu.pl/~nbbienia |
*-------------------------------------------------------------------*
 
J

Jacques Labuschagne

Leslaw said:
Cracow, 20.10.2004

Hello,

As far as I understand, the generic programming basically consists
in using templates for achieving a static polymorphism of the
various code fragments, and their reuse for various template
parameters. I wonder if there exist techniques for achieving
a dynamic polymorphism using the generic programming. Is this
possible? If yes, can anyone show me simple examples in C++
of how this can be done?

It all depends on how narrowly you define "generic programming". Do you
restrict it to compile-time constructs like templates, or do you broaden
the definition to encompass other methods of maintaining a consistent
interface across many different actual types.

Virtual functions are the standard way of implementing dynamic
polymorphism, but templates can indeed be a big help. Consider the
example of a "callback" template.

class adapter_base{
public:
virtual ~adapter_base(){}
virtual void operator()() = 0;
};

template<typename T>
class adapter: public adapter_base{
T& object;
public:
explicit adapter(T& t): object(t){}
virtual void operator()(){ object(); }
};


class callback_executer{
std::vector<adapter_base*> callbacks;
public:
template<typename T>
void add_callback(const T& t){
callbacks.push_back(new adapter(t));
}
void execute_all(){
for (std::vector<adapter_base*>::iterator i = callbacks.begin();
i != callbacks.end();
++i)
{
(*(*i))();
}
}
~callback_executer(){
for (std::vector<adapter_base*>::iterator i = callbacks.begin();
i != callbacks.end();
++i)
{
delete *i;
}
}
};


struct callback_A{
void operator()(){
std::cout << "callback A executed!\n";
}
};

struct callback_B{
void operator()(){
std::cout << "callback B executed!\n";
}
};

int main(){
callback_executer c;
c.add_callback(callback_A());
c.add_callback(callback_B());
c.execute_all();
}


Regards,
Jacques.
 
V

Victor Bazarov

Jacques said:
It all depends on how narrowly you define "generic programming". Do you
restrict it to compile-time constructs like templates, or do you broaden
the definition to encompass other methods of maintaining a consistent
interface across many different actual types.

Virtual functions are the standard way of implementing dynamic
polymorphism, but templates can indeed be a big help. Consider the
example of a "callback" template.

I've made some corrections below, which do not diminish the value of
the example, only fix some bugs to make it compilable.
class adapter_base{
public:
virtual ~adapter_base(){}
virtual void operator()() = 0;
};

template<typename T>
class adapter: public adapter_base{
T& object;
public:
explicit adapter(T& t): object(t){}
virtual void operator()(){ object(); }
};

#include said:
class callback_executer{
std::vector<adapter_base*> callbacks;
public:
template<typename T>
void add_callback(const T& t){

void add_callback(T& t) {
callbacks.push_back(new adapter(t));

callbacks.push_back(new adapter said:
}
void execute_all(){
for (std::vector<adapter_base*>::iterator i = callbacks.begin();
i != callbacks.end();
++i)
{
(*(*i))();
}
}
~callback_executer(){
for (std::vector<adapter_base*>::iterator i = callbacks.begin();
i != callbacks.end();
++i)
{
delete *i;
}
}
};

#include said:
struct callback_A{
void operator()(){
std::cout << "callback A executed!\n";
}
};

struct callback_B{
void operator()(){
std::cout << "callback B executed!\n";
}
};

int main(){
callback_executer c;
c.add_callback(callback_A());
c.add_callback(callback_B());

Can't use temporaries. Have to declare real objects.

callback_A a;
c.add_callback(a);
callback_B b;
c.add_callback(b);

Otherwise, the code has to be severely const-corrected.
c.execute_all();
}

V
 
J

Jacques Labuschagne

Victor said:
I've made some corrections below, which do not diminish the value of
the example, only fix some bugs to make it compilable.

Thanks. :)


Jacques.
 
L

Leslaw Bieniasz

Cracow, 21.10.2004

Hello,

It all depends on how narrowly you define "generic programming". Do you
restrict it to compile-time constructs like templates, or do you broaden
the definition to encompass other methods of maintaining a consistent
interface across many different actual types.

Virtual functions are the standard way of implementing dynamic
polymorphism, but templates can indeed be a big help. Consider the
example of a "callback" template.


What I have in mind is whether one can avoid using virtual functions,
but achieve the same effect of dynamic polymorphism using only templates.
The virtual functions allow one to differentiate the behaviour of objects
depending on the dynamic, run-time type of the object. However, in
principle the types of all objects created within a program are always
exactly known at the moment of their creation. Therefore, one might
expect (at least theoretically) that if this static, compile-time type
information could be passed somehow to the code that calls the object
methods, then one could avoid using the virtual functions, but obtain
the same polymorphic behaviour. This might be pretty complicated to
do, I suppose.

My question is motivated by my attempts to understand some
existing libraries, like the matrix algebra library MTL, which
is said to use generic programming and templates. Various types
of vectors/matrices are there defined as templates, each one for
one matrix/vector type, and dynamic polymorphism is avoided (I may
be wrong though). Therefore, there does not seem to be anything
like a base matrix or vector class, from which all types are derived.
I therefore do not see a way to write polymorphic constructs
such as for example

Add(a,b,c)

which could perform addition c = a+b

of various types of vectors or matrices, assuming that a,b and c
are pointers or references to the base type. Instead, one always
have to specify to which particular types the a, b and c point/refer
to, whenever a,b and c are declared. This appears a severe limitation
to me, because various parts of the code must always be specialised,
or occur as templates with many parameters (representing, for example the
types of a, b, and c in the above example). Therefore, I am asking if
there exist techniques that would allow me to achieve dynamic polymorphism
without using class hierarchies with virtual functions.

L.B.


*-------------------------------------------------------------------*
| Dr. Leslaw Bieniasz, |
| Institute of Physical Chemistry of the Polish Academy of Sciences,|
| Department of Electrochemical Oxidation of Gaseous Fuels, |
| ul. Zagrody 13, 30-318 Cracow, Poland. |
| tel./fax: +48 (12) 266-03-41 |
| E-mail: (e-mail address removed) |
*-------------------------------------------------------------------*
| Interested in Computational Electrochemistry? |
| Visit my web site: http://www.cyf-kr.edu.pl/~nbbienia |
*-------------------------------------------------------------------*
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top