Re: templated virtual functions??
In article
<cccacfbc-75f5-4102-b8cc-71526127bf20@1g2000prf.googlegroups.com>,
<jorka2@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! ]