Re: double dispatch, half compile-time
On Mar 2, 9:19 am, Ethan Eade <e...@cam.ac.uk> wrote:
I have a hierarchy that looks like this:
-----------
class Variant {
public:
virtual ~Variant(){}
};
template <class T> class Value<T> : public Variant {
private:
T value;
public:};
------------
Let's say there are two function templates:
------------
template <class A>
void single_bound(const A& a, const Variant& b);
template <class A, class T>
void double_bound(const A& a, const Value<T>& v);
------------
Is there any possible implementation of single_bound such that the
appropriate double_bound would be called inside? That is, can Variant
and Value<T> be defined s.t. their definitions do not explicitly list
the possibilities for type A, but still both A and T can be known
in the
same scope?
Conceptually, I would like it to look like this (this is not valid C
++):
-------------
class Variant {
public:
virtual ~Variant(){}
template <class A> virtual void foo(const A& a) const = 0;
};
template <class T> class Value<T> : public Variant {
private:
T value;
public:
template <class A> virtual void foo(const A& a) const {
double_bound(a, *this);
}
};
template <class A>
void single_bound(const A& a, const Variant& b) {
b.foo(a);}
-------------
The above is not legal because of the virtual template. However, the
compiler knows the type A at compile time, and within a virtual
function
of Variant, it knows type T as well. Can it know both simultaneously?
So far, I conclude it cannot. Keep in mind, the possibilities for A
cannot be explicitly mentioned in the interface of Variant.
One solution would probably be to use External Polymorphism, like:
template <class A>
struct I
{
virtual void foo(const A& a) = 0;
};
template <class T, class A>
void adapt(T* t, const A& a)
{
t->foo(a);
}
template <class T, class A>
struct Adapter : I<A>
{
Adapter(T& t) : t_(&t){}
virtual void foo(const A& a)
{
adapt(t_, a);
}
private:
T* t_;
};
struct Variant
{
template <class A>
void foo(const A& a)
{
std::cout << "I'm a Variant\n" ;
}
};
template <class T>
struct Value
{
template <class A>
void foo(const A& a)
{
std::cout << "I'm a Value\n" ;
}
};
template <class A>
void single_bound(const A& a, I<A>* i) {
i->foo(a);
}
int main()
{
Variant v;
Value<int> val;
Adapter<Variant, long> av(v);
I<long> *iV = &av;
Adapter<Value<int>, long> aval(val);
I<long> *iVal = &aval;
std::vector<I<long>* > vec;
vec.push_back(iV);
vec.push_back(iVal);
for (std::vector<I<long>* >::iterator i = vec.begin();
i != vec.end() ; ++i)
{
single_bound(1l, *i);
}
return 0;
}
HTH
Radu
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]