473,324 Members | 2,548 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,324 software developers and data experts.

Multiple dispatch using templates - too good to be true?

Greetings,

I too have succumbed to the perhaps foolish urge to write a video
game, and I have been struggling with the implementation of multiple
dispatch. I read through "More Effective C++" by Scott Meyers, and
though I am impressed with his implementation, I wanted to find a way
to use multiple dispatch in a way that was less complicated.
Forgive me if the result, below, has been posted before or written of
before - I haven't read the "Purple Book" at all, so maybe it's all
been done before. What I'd like to know is what I'm missing - this
compiles on my machine, but am I doing something horribly wrong by
trying this? If I add a class later, like one out of a dynamically-
linked library, am I going to have to recompile everything? It just
seems to be too easy to be true.

//File: base_dispatch.h
#ifndef __BASEDISPATCH__
#define __BASEDISPATCH__

class BaseDispatcher
{
public:
virtual void Dispatch(void* A) = 0;
};
#endif

//File: dispatchany.cpp
#ifndef __DISPATCHANY__
#define __DISPATCHANY__

#include "base_dispatcher.h"

template<class T=BaseDispatcher, class U=BaseDispatcher>
class DispatchAny
{
public:
static void Dispatch(T* dispatcher, void* arg)
{
dispatcher->Dispatch(arg);
}

static void Dispatch(T* dispatcher, U* arg)
{
dispatcher->Dispatch(arg);
}
};
#endif

//File: testdispatchany.cpp
#include "dispatchany.cpp"
#include <iostream>

using std::cout;
using std::endl;

class Attack;
class Ability
{
public:
virtual void Dispatch(void* A) { cout<<"Dispatched to void in
ability"<<endl; }
virtual void Dispatch(Attack* a) { cout<<"Ability dispatches
attack"<<endl; }
};
class Attack
{
public:
virtual void Dispatch(void* A) { cout<<"Dispatched to void in
attack"<<endl; }
virtual void Dispatch(Ability* a) { cout<<"Attack dispatches
ability"<<endl; }
};
class Melee : public Attack
{
public:
virtual void Dispatch(void* A) { cout<<"Dispatched to void in
melee"<<endl; }
virtual void Dispatch(Ability* a) { cout<<"Melee dispatches
ability"<<endl; }
};
int main()
{
Ability* a = new Ability();
Attack* b = new Attack();

int* test = new int(5);

Melee* melee = new Melee();

DispatchAny<Ability, Attackc;
DispatchAny<Attack,Abilityd;
DispatchAny<Melee,Abilitye;

c.Dispatch(a,b);
d.Dispatch(b,a);
e.Dispatch(melee,a);
d.Dispatch(melee,a);
c.Dispatch(a,a);
c.Dispatch(a,test);

delete a;
delete b;
delete melee;
delete test;

return 0;
}
I seek the wisdom of the opinions of those more experienced than I,
and I thank you for them.

Apr 30 '07 #1
3 3757
Tigera wrote:
Greetings,
//File: base_dispatch.h
#ifndef __BASEDISPATCH__
#define __BASEDISPATCH__
//File: dispatchany.cpp
#ifndef __DISPATCHANY__
#define __DISPATCHANY__

[redacted]
I seek the wisdom of the opinions of those more experienced than I,
and I thank you for them.
Do not use two consecutive underscores in your include guards, or in any
other identifier. Any such identifier is reserved to the implementation
(compiler vendor), also, any identifier with a single leading underscore
followed by an upper case letter is so reserved.

Your program is therefore ill-formed.
Apr 30 '07 #2
On Apr 29, 10:34 pm, red floyd <no.s...@here.dudewrote:
Tigera wrote:
Greetings,
//File: base_dispatch.h
#ifndef __BASEDISPATCH__
#define __BASEDISPATCH__
//File: dispatchany.cpp
#ifndef __DISPATCHANY__
#define __DISPATCHANY__
[redacted]
I seek the wisdom of the opinions of those more experienced than I,
and I thank you for them.

Do not use two consecutive underscores in your include guards, or in any
other identifier. Any such identifier is reserved to the implementation
(compiler vendor), also, any identifier with a single leading underscore
followed by an upper case letter is so reserved.

Your program is therefore ill-formed.
Interesting. I've never heard of that before. Like I said, it
compiled and ran OK, though I did change the code as you prescribed.
I've been using include guards with double-underscores for years -
looks like I've been messing that up for a while. Thanks for the
correction. The code still compiles and runs after this, do you see
any other problems?

Apr 30 '07 #3
Tigera wrote:
Greetings,

I too have succumbed to the perhaps foolish urge to write a video
game, and I have been struggling with the implementation of multiple
dispatch. I read through "More Effective C++" by Scott Meyers, and
though I am impressed with his implementation, I wanted to find a way
to use multiple dispatch in a way that was less complicated.
Forgive me if the result, below, has been posted before or written of
before - I haven't read the "Purple Book" at all, so maybe it's all
been done before. What I'd like to know is what I'm missing - this
compiles on my machine, but am I doing something horribly wrong by
trying this? If I add a class later, like one out of a dynamically-
linked library, am I going to have to recompile everything? It just
seems to be too easy to be true.

//File: base_dispatch.h
#ifndef __BASEDISPATCH__
#define __BASEDISPATCH__

class BaseDispatcher
{
public:
virtual void Dispatch(void* A) = 0;
};
#endif

//File: dispatchany.cpp
#ifndef __DISPATCHANY__
#define __DISPATCHANY__

#include "base_dispatcher.h"

template<class T=BaseDispatcher, class U=BaseDispatcher>
class DispatchAny
{
public:
static void Dispatch(T* dispatcher, void* arg)
{
dispatcher->Dispatch(arg);
}

static void Dispatch(T* dispatcher, U* arg)
{
dispatcher->Dispatch(arg);
}
};
#endif

//File: testdispatchany.cpp
#include "dispatchany.cpp"
#include <iostream>

using std::cout;
using std::endl;

class Attack;
class Ability
{
public:
virtual void Dispatch(void* A) { cout<<"Dispatched to void in
ability"<<endl; }
virtual void Dispatch(Attack* a) { cout<<"Ability dispatches
attack"<<endl; }
};
class Attack
{
public:
virtual void Dispatch(void* A) { cout<<"Dispatched to void in
attack"<<endl; }
virtual void Dispatch(Ability* a) { cout<<"Attack dispatches
ability"<<endl; }
};
class Melee : public Attack
{
public:
virtual void Dispatch(void* A) { cout<<"Dispatched to void in
melee"<<endl; }
virtual void Dispatch(Ability* a) { cout<<"Melee dispatches
ability"<<endl; }
};
int main()
{
Ability* a = new Ability();
Attack* b = new Attack();

int* test = new int(5);

Melee* melee = new Melee();

DispatchAny<Ability, Attackc;
DispatchAny<Attack,Abilityd;
DispatchAny<Melee,Abilitye;

c.Dispatch(a,b);
d.Dispatch(b,a);
e.Dispatch(melee,a);
d.Dispatch(melee,a);
c.Dispatch(a,a);
c.Dispatch(a,test);

delete a;
delete b;
delete melee;
delete test;

return 0;
}
I seek the wisdom of the opinions of those more experienced than I,
and I thank you for them.
I fail to see where you actually do multiple dispatch. The dispatch
seems to only occur on the first parameter. If you want to, say
dispatch on Attack and Ability the setup would be something like:

struct Ability;

struct Attack
{
virtual void Dispatch(Ability *) = 0;
};

struct Melee;
struct Projectile;

struct Ability
{
virtual void Dispatch(Melee *) = 0;
virtual void Dispatch(Projectile *) = 0;
};

void Dispatch(Attack *attack, Ability *ability)
{
attack->Dispatch(ability);
}

With Melee and Projectile looking something like:

struct Melee : Attack
{
void Dispatch(Ability *ability)
{
ability->Dispatch(this);
}
};

struct Projectile : Attack
{
void Dispatch(Ability *ability)
{
ability->Dispatch(this);
}
};

To avoid repeating the boiler plate the curiously recurring template
pattern can be used:

template<class T>
struct AttackDispatch : Attack
{
void Dispatch(Ability *ability)
{
ability->Dispatch(static_cast<T *>(this));
}
};

struct Melee : AttackDispatch<Melee>
{
};

struct Projectile : AttackDispatch<Projectile>
{
};

This will be even more useful if there are multiple multiple dispatch
functions (no pun intended).

But maybe I am just misunderstanding what you are trying to do.

--
Markus

Apr 30 '07 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Thomas Heller | last post by:
I'm currently reinventing the wheel ;-), implementing 'clones' for the win32com.client.Dispatch and DispatchWithEvents functions using ctypes. It works fairly well, although the more complicated...
31
by: Chris S. | last post by:
Is there a purpose for using trailing and leading double underscores for built-in method names? My impression was that underscores are supposed to imply some sort of pseudo-privatization, but would...
4
by: Leslaw Bieniasz | last post by:
Cracow, 20.09.2004 Hello, I need to implement a library containing a hierarchy of classes together with some binary operations on objects. To fix attention, let me assume that it is a...
20
by: km | last post by:
Hi all, In the following code why am i not able to access class A's object attribute - 'a' ? I wishto extent class D with all the attributes of its base classes. how do i do that ? thanks in...
8
by: J. Black | last post by:
Hello everyone - I've been developing an incident tracking and reporting system for an emergency services outfit that I work with part time. It's going well, except for one fly in the ointment....
32
by: tshad | last post by:
Can you do a search for more that one string in another string? Something like: someString.IndexOf("something1","something2","something3",0) or would you have to do something like: if...
6
by: G.Ashok | last post by:
Hi, Does anybody know how Multiple polymorphism can be done in VB.NET or DOT doesn't support it? Is there any third party extensions available like for Java to do this? Regards, ....Ashok...
7
by: Dave | last post by:
Apologies for the newbie question. I have created a vb.net program for my company that is designed to work with Word Templates (about forty of them that we commonly use) that are selected by the...
3
by: tyler.schlosser | last post by:
Hi there, I am trying to launch a program called AmiBroker using the command: AB = win32com.client.Dispatch("Broker.Application") However, I have a dual-core CPU and would like to launch two...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.