Re: Multiple dispatch
jam wrote:
struct A{
virtual void go();
};
struct B{
virtual void go();
};
struct C{
virtual void go();
};
struct D{
virtual void go();
};
if a class inherits any two of the above then it will have to define
its own version of go that will replace in both vtables inherited.
Here is a humble syntax proposal:
struct all: A,B,C,D{
// here is the syntax:
void go() A{cout<<'A';};//override A::go
void go() B{cout<<'B';};//override B::go
void go(){cout<<"all";};//used for C,D and all
};
all * ptr=new all;
ptr->go();//prints 'all'
((A*)ptr)->go();//prints 'A'
((B*)ptr)->go();//prints 'B'
((C*)ptr)->go();//prints 'all'
((D*)ptr)->go();//prints 'all'
vtables of A and B got different versions of go than C and D and if
any class inherits 'struct all' then by default it will use theversoin
of go that prints 'all' unless it is casted to A or be or redefines
go.
Probably it can be done, but for
void go(){cout<<"all";}; //used for C,D and all
you will need entry in vtable of struct "all" for "all::go()", that
normally can be avoided (any vtable of base class can be used to find
"(all*)(ptr)->go();" ).
But what the practical puprose of the kind of separatedly overloaded
base methods? I do not see any.
Also why have you called this stuff as "multiple dispath"? It looks
like special implemetation of "single dispatch" with "type of class"
as single dispatch selector.
As i know multiple dispatch is something, that has other dispath
selectors, in addition to "class of object", for example, first
parametter of function can be second dispatch selector.
struct Base
{
virtual void foo(const Base&)=0;
};
struct Derived: public Base
{
void foo(const Base&);
dispatched void foo(const Derived&);
dispatched void foo(const int);
};
struct Extra: public Derived
{
void foo(const double);
};
Here all "foo" with only one parameter became "dispatched" for class
Derived and for all classes inherited from Derived.
extern Base auto* param;
Base heap* ptr=new Derived;
void foo()
{
ptr->foo(*param);
}
Here "Derived::foo(const Base&)" will be called if
"typeid(*param)==typeid(Base)" and "Derived::foo(const Derived&)" will
be called if "typeid(*param)==typeid(Derived)".
It looks like
Base::vtbl[foo_offset](*param);
here called C++ generated
Derived::virtual_to_dispatcher( param );
void Derived::virtual_to_dispatcher( param )
{
Derived::dispatcher_foo( typeid(param), param );
}
here called C++ generated
Derived::dispatcher_foo( typeid(param), param )
void Derived::dispatcher_foo( const typeid& id, ... )
{
va_list param;
va_start(param, id);
if( id == typeid(const int) )
{
const int tmp=va_arg(param,const int);
va_end(param);
[return] Derived::foo( (const int)param );
[return;]
}
if( id == typeid(Derived) )
{
Derived& tmp=va_arg(param,Derived&);
va_end(param);
[return] Derived::foo( (Derived&)param );
[return;]
}
//if( id == typeid(Base) )
{
Base& tmp=va_arg(param,Base&);
va_end(param);
[return] Derived::foo( (Base&)param );
[return;]
}
//execution control never reach the point
//due to static type checking
}
void boo()
{
Base b;
Derived d;
Extra e;
b.foo(*ptr);
b.foo(b);
b.foo(d);
b.foo(e);
d.foo(*ptr);
d.foo(b);
d.foo(d);
d.foo(e);
d.foo(100);
e.foo(*ptr);
e.foo(b);
e.foo(d);
e.foo(100);
e.foo(0.1);
}
Of course, multiple dispatching is doing by the cost of perfomans
lost.
--
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]