From: Carl Barron on
In article
<cccacfbc-75f5-4102-b8cc-71526127bf20(a)1g2000prf.googlegroups.com>,
<jorka2(a)hotmail.com> wrote:

>
> So my questions are:
> 1. Why isn't templated virtual functions allowed in C++?
> 2. Is there an reasonably simple way around this? Or can I change my
> design some way and have both decoupling and still be able to have an
> parameterized implementation of a tree structure?
a templated virtual function will require a variable sized vtable in
effect that is sizeof(Interface) is not constant. Lots of problems...

Now a work around, you if you know all possible T's at compile time
then you can do can create all the private virtual functions with a
dummy argument to select the T and call the proper virtual function
with a public non-virtual function.

#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/enable_if.hpp>

class interface
{
#define INTERFACE_INTERNAL_TYPES (A1)(A2)(A3)
#define INTERFACE_INTERNAL_VIRT_FUNC(R,D,X)\
virtual X* internal_get(boost::mpl::identity<X>) {return 0;}
BOOST_PP_SEQ_FOR_EACH(INTERFACE_INTERNAL_VIRT_FUNC,~,
INTERFACE_INTERNAL_TYPES)
#undef INTERFACE_INTERNAL_VIRT_FUNC
protected:
interface(){}
public:
template <class T>
boost::enable_if
{
boost::mpl::contains
<
boost::mpl::vector<
BOOST_PP_SEQ_ENUM(INTERFACE_INTERNAL_TYPES)
#undef INTERFACE_INTERNAL_TYPES
>,
T
>
T *
>::type get_value()
{ return internal_get(boost::mpl::identity<T>());}
virtual ~interface(){}
};

this generates a list of virtual functions in the private access part
of interface
virtual A1 *internal_get(boost::mpl::identity<A1>) {return 0;}
virtual A2 *internal_get(boost::mpl::identity<A2>) {return 0;}
virtual A3 *internal_get(boost::mpl::identity<A3>) {return 0;}
I used boost::mpl::identity to create a cheap to construct struct. so
the argument of each virt. function is different.

I returned a ptr so that I have a defined result if there is no
provided internal_get(boost::mpl::identity<X>) outside of the interface
classs. This will not compile if T is not one of A1,A2,A3 as well

INTERFACE_INTERNAL_TYPES is just a list of classes enclosed in parens
like the example above. Works fine as long as long as the list has
less than 256 types and probably even then unless the resources of the
preprocessor are exhausted.

to add new types just modify the #define INTERNAL_INTERFACE_TYPES ...

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Mathias Gaunard on
On 9 avr, 21:13, Carl Barron <cbarron...(a)adelphia.net> wrote:

> a templated virtual function will require a variable sized vtable in
> effect that is sizeof(Interface) is not constant. Lots of problems...

A way to implement template virtual functions would be to generate
those vtables at link-time.
Which causes problems with runtime linking, of course.

template virtual functions would be totally awesome, though.
You could have a function type, for example. Implement duck-typing
efficiently and well integrated in the language.
Basically, it would bring the template mechanism to runtime.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]