template specialization



 DEVELOP > c-Plus-Plus > template specialization

LINK TO THIS PAGE  


rating :  0   |  0


  Page 1 of 1

1

 
Topic: DEVELOP > c-Plus-Plus
User: "Eric"
Date: 20 Nov 2003 05:32:44 PM
Object: template specialization
Does anyone know if you can specialize a template function for
arguments that are pointers to a particular base class and not lose
the subclass type?
example:
template <class E>
void DeliverEvent(E *Event);
is a function that will receive an Event object, and then eventually
pass it to the proper destination. To avoid downcasting, any
destination will have a "ReceiveEvent" function that is overloaded for
each specific Event class it is interested in.
There is a particular class of Events, call them "CallEvents", which
require special processing before passing them along. So I want to
specialize the function as such:
template <>
void DeliverEvent(CircuitEvent *Event);
But in doing it this way, the Event object becomes a base class
pointer, and I lose its specific type (and I would like to avoid
downcasting to regain it).
Is there a way to specialize the template function so that my template
argument keeps it type?
Thanks,
Eric Simon
.

User: "Jeff"

Title: Re: template specialization 20 Nov 2003 11:51:33 PM
Hey Eric, I must be missing something here, hope I don't make a total
fool of myself ...

template <class E>
void DeliverEvent(E *Event);
template <>
void DeliverEvent(CircuitEvent *Event);

Don't you need to specify the type in the specialization (hope I've
got this right...) ?
template <>
void DeliverEvent<CircuitEvent>(CircuitEvent* Event);
------------
Second, if you're dealing with a class heirarchy, why do you need to
use templates here at all? Can't you just overload the function?
(pardon the silly question)
void DeliverEvent(Event* e);
void DeliverEvent(CircuitEvent* e);
Jeff
.
User: "Eric"

Title: Re: template specialization 21 Nov 2003 08:52:40 AM
(Jeff) wrote in message news:<7b01eaf3.0311202151.25af8fd0@posting.google.com>...

Hey Eric, I must be missing something here, hope I don't make a total
fool of myself ...

template <class E>
void DeliverEvent(E *Event);
template <>
void DeliverEvent(CircuitEvent *Event);


Don't you need to specify the type in the specialization (hope I've
got this right...) ?
template <>
void DeliverEvent<CircuitEvent>(CircuitEvent* Event);

Yes, you are right. My mistake.

------------

Second, if you're dealing with a class heirarchy, why do you need to
use templates here at all? Can't you just overload the function?
(pardon the silly question)
void DeliverEvent(Event* e);
void DeliverEvent(CircuitEvent* e);

The problem is that Event and Circuit Event are base classes. There
are several concrete classes that inherit from Event. Circuit Event
also inherits from Event, and in turn, has several concrete classes
inheriting from it. I use templates because I don't want to have to
downcast to regain the subclass type. I guess it's a very weak
hierarchy - the base class has very little functionality. Most of the
interesting stuff is specific to each subclass.
Thanks,
Eric


Jeff

.
User: "Jeff"

Title: Re: template specialization 21 Nov 2003 01:12:48 PM

Second, if you're dealing with a class heirarchy, why do you need to
use templates here at all? Can't you just overload the function?
(pardon the silly question)
void DeliverEvent(Event* e);
void DeliverEvent(CircuitEvent* e);


The problem is that Event and Circuit Event are base classes. There
are several concrete classes that inherit from Event. Circuit Event
also inherits from Event, and in turn, has several concrete classes
inheriting from it. I use templates because I don't want to have to
downcast to regain the subclass type.

I'm still puzzled as to why you need templates, though ... shouldn't
polymorphism do the trick? In Scott Meyers's "Effective C++, 2nd ed",
Item 41 says "Differentiate between inheritance and templates" -- the
section is aimed at class templates, but can be generalized to
functions as well. The summary of the item, copied from the book, is
here:
- A template should be used to generate a collection of classes when
the type of the objects /*does not*/ affect the behaviour of the
class's functions.
- Inheritance should be used for a collection of classes when the type
of the objects /*does*/ affect the behaviour of the class's functions.
Since you're talking about changing the behaviour of a particular
function depending on the type of item passed to it, polymorphism (or,
in this case, function overloading) seems to be called for...
But perhaps I'm missing something. Can you boil your problem down to
a simple representation and post it? That way I (and others) might be
able to comment more appropriately on your problem (perhaps creating a
new thread in this group, and copying the messages from this thread to
the new post).
Jeff
.



User: "tom_usenet"

Title: Re: template specialization 21 Nov 2003 08:03:29 AM
On 20 Nov 2003 15:32:44 -0800,
(Eric) wrote:

Does anyone know if you can specialize a template function for
arguments that are pointers to a particular base class and not lose
the subclass type?

example:

template <class E>
void DeliverEvent(E *Event);

is a function that will receive an Event object, and then eventually
pass it to the proper destination. To avoid downcasting, any
destination will have a "ReceiveEvent" function that is overloaded for
each specific Event class it is interested in.

There is a particular class of Events, call them "CallEvents", which
require special processing before passing them along. So I want to
specialize the function as such:

template <>
void DeliverEvent(CircuitEvent *Event);

But in doing it this way, the Event object becomes a base class
pointer, and I lose its specific type (and I would like to avoid
downcasting to regain it).

Is there a way to specialize the template function so that my template
argument keeps it type?

Yes, but it's a bit complicated (first download boost from
www.boost.org).
Basically you don't specialize the template, but instead dispatch to a
particular implementation based on properties of the passed type. In
this case, your looking for SpecialEvent and classes derived from it.
#include <iostream>
#include <boost/type_traits.hpp>
using namespace boost;
struct Event
{
};
struct SpecialEvent
{
virtual ~SpecialEvent() {}
void non_virtual()
{
std::cout << "SpecialEvent::non_virtual\n";
}
};
struct DerivedSpecialEvent: SpecialEvent
{
void non_virtual()
{
std::cout << "DerivedSpecialEvent::non_virtual\n";
}
};
template <bool>
struct DeliverEventImpl
{
template <class Event>
static void do_it(Event* event)
{
std::cout << "Non specialized\n";
}
};
template<>
struct DeliverEventImpl<true>
{
//SpecialEvent version
template <class Event>
static void do_it(Event* event)
{
event->non_virtual();
}
};
template <class E>
void DeliverEvent(E* event)
{
DeliverEventImpl<
is_base_and_derived<SpecialEvent, E>::value
|| is_same<SpecialEvent, E>::value

::do_it(event);

}
int main()
{
Event e;
SpecialEvent se;
DerivedSpecialEvent dse;
DeliverEvent(&e);
DeliverEvent(&se);
DeliverEvent(&dse);
}
Tom
.


  Page 1 of 1

1

 


Related Articles
 

NEWER

pg.1232     pg.940     pg.716     pg.544     pg.412     pg.311     pg.234     pg.175     pg.130     pg.96     pg.70     pg.50     pg.35     pg.24     pg.16     pg.10     pg.6     pg.3     pg.1

OLDER