By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,305 Members | 1,588 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,305 IT Pros & Developers. It's quick & easy.

template specialization

P: n/a
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
Jul 22 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
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
Jul 22 '05 #2

P: n/a
On 20 Nov 2003 15:32:44 -0800, pu*****@hotmail.com (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
Jul 22 '05 #3

P: n/a
je********@yahoo.com (Jeff) wrote in message news:<7b**************************@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

Jul 22 '05 #4

P: n/a
> > 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
Jul 22 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.