   [C++] Avoid/retrieve type of templated instances in a heterogeneous array?
  Well, I feel stuck in this (rather complex) problem; there's a previous thread about it, but only now I release what the problem is...I have BaseClass' stored in a vector. From this BaseClass multiple templated classes derive. When you allocate a derived class, you pass the template parameters and push it onto the vector. However, from now on we forget the type information of the template parameters...At a later point, I want to remove some elements off the array based on their (partial) type. How do I solve this?Since a piece of code says more then a 1000 words:class Base{};template <class T, class S>class Derived: public Base{public:    T t;    S s;};class Array{public:    std::vector<Base *> vector;    template <class T, class S>    void add(T t, S s)    {   Derived *derived = new Derived;   derived->t = t;   derived->s = s;   vector.push_back(derived);    }    template <class T>    void remove(T t)    {   for (std::vector<Base *>::iterator iterator = vector.begin(); iterator != vector.end(); ++iterator)   {  if ((*iterator)->t == t) // invalid, but you get what I want  { // delete the vector element  }   }    }    template <class S>    void remove(S s)    {   for (std::vector<Base *>::iterator iterator = vector.begin(); iterator != vector.end(); ++iterator)   {  if ((*iterator)->s == s) // invalid, but you get what I want  { // delete the vector element  }   }    }    template <class T, class S>    void remove(T t, S s)    {   for (std::vector<Base *>::iterator iterator = vector.begin(); iterator != vector.end(); ++iterator)   {  if ((*iterator)->t == t && (*iterator)->s == s) // invalid, but you get what I want  { // delete the vector element  }   }    }};You can view T as a pointer to a class instance and S being a member function pointer.Thank you   
  OK, and why would you want to do something like that?   ;  I'm with Zahlman here - this can probably be accomplished with liberal application of dark magic, but there'd better be a fantastic reason.The first thing that comes to mind is a simple pure virtual function in your Base class that you can use to ask an individual element if it meets the given criteria for removal from the container.   ;  Well, the obvious way to do this is to remember what the types are inside your derived class using the templating system. The trick here is to invert your problem. Don't write code which checks to see if the object is the right type from outside -- ask the object itself. It's the one which knows...So what you do, is make your base class have a virtual function, like this;virtual bool areYou(const std::type_info *s_cand,const std::type_info *t_cand)=0; Your derived can easily implement this..virtual bool areYou(const type_info *s_cand,const type_info *t_cand){  if (s_cand)    if (typeid(S)!=(*s_cand)) return false;  if (t_cand)    if (typeid(T)!=(*t_cand)) return false;  return true;} S and T here, of course, are filled in by your classes template params.Now the test inside the loop is a call into the object, passing in the type you want to ask it if is; template <class T>    void remove(T t)    {   for (std::vector<Base *>::iterator iterator = vector.begin(); iterator != vector.end(); ++iterator)   {  if ((*iterator)->areYou(&typeid(T),0)  { // delete the vector element  }   }    }The dual check is similar. You could write multiple areYou()s to avoid the null checks, but this illustrates the general idea.This is a useful approach in OO engineering -- if you get stuck trying to do something, see if you can swap the functionality into another object and see if it makes more sense there.;Quote:Original post by ApochPiQThe first thing that comes to mind is a simple pure virtual function in your Base class that you can use to ask an individual element if it meets the given criteria for removal from the container.Yes, but the virtual function would need to be templated to pass along one of the templated data members...and virtual and templates are not allowed. I've tried the visitor pattern but got stuck at the point where I need to templatize virtual member functions =/Quote:Original post by ZahlmanOK, and why would you want to do something like that?Well, if you see T as a pointer to a class instance and S being a member function pointer, I want to be able to just remove items of one certain class instance, no matter what the member function pointer is.It is for a signal and slot system.@KatieThanks for that, I hadn't thought of that yet![Edited by - Decrius on June 6, 2010 1:34:26 PM];  @KatieThat is indeed a useful way to check whether the type are equal (and thus if we can cast a Base* to Derived<T, S>* with specified T and S safely), but it doesn't check whether the values of the types are equal.Say, the user passes a T and an S type, if, using your method, T and S equal the types in a Derived, then we cast the Base* from the vector to a Derived<T, S>* and we can call a method in Derived to check whether the values are equal.But what if the user only passes a T type, we can't cast Base* to Derived<T, S>* since we don't know S.I can use void-pointer, that would simplify things A LOT. Is there any hidden undefined-behaviour for using void*?Somehow it feels like C++ has a fault in it's syntax / reasoning (but I'm probably wrong, so please correct me :-)). The reason why virtual functions cannot be templated is that the compiler then doesn't know the size of the table and the offsets. But what if you use templated pointers, or templated function pointers...pointers are the same size (aren't they?) so then the compiler can still have a definite length for the return / arguments...This works:// this also can only work because I know my derived classes will only either have one or two types they holdclass Base{public:    virtual bool type(const std::type_info &tt)    {   return false;    }    virtual bool type(const std::type_info &tt, const std::type_info &ts)    {   return false;    }    virtual bool value(void *a) // void* because C++ doesn't allow templated virtual functions, only called when the actual type of 'a' equals that of derived class type T    {   return false;    }    virtual bool value(void *a, void *b)    {   return false;    }};template <class T, class S>class Derived: public Base{public:    T *t;    S *s;    bool type(const std::type_info &tt)    {   return (typeid(T) == tt);    }    bool type(const std::type_info &tt, const std::type_info &ts)    {   return (typeid(T) == tt && typeid(S) == ts);    }    bool value(void *a)    {   return (t == a);    }    bool value(void *a, void *b)    {   return (t == a && s == b);    }};class Array{public:    std::vector<Base *> vector;    template <class T, class S>    void add(T *t, S *s)    {   Derived<T, S> *derived = new Derived<T, S>();   derived->t = t;   derived->s = s;   vector.push_back(derived);    }    template <class T>    void remove(T *t)    {   for (std::vector<Base *>::iterator iterator = vector.begin(); iterator != vector.end(); ++iterator)   {  if ((*iterator)->type(typeid(T)))  { std::cerr << "type equal\n"; if ((*iterator)->value(t)) // we know the types equal {std::cerr << "value equal\n"; } else {std::cerr << "value unequal\n"; }  }  else  { std::cerr << "type unequal\n";  }   }    }} [Edited by - Decrius on June 7, 2010 8:55:09 AM];  How _bad_ is it to reinterpret cast any function pointer to a void(*)(void)?According to this thread it is, however, I'm never calling the function after reinterpret cast, I only check whether the pointer are equal:typedef void (*VOID_FUNCTION_POINTER)(void);int f(char c){    return 1;}template <class T, class S>class Derived: public Base{    typedef T (*FUNCTION)(S);    public:    FUNCTION function;    bool equal(const std::type_info &type, VOID_FUNCTION_POINTER value) const    {   // we only check the value here, never call the function after castings   return (typeid(function) == type && function == reinterpret_cast<FUNCTION>(value));    }};int main(){    Derived<int, char> *derived = new Derived<int, char>();    derived->function = &f;    // how bad is the following    if (derived->equal(typeid(&f), reinterpret_cast<VOID_FUNCTION_POINTER>(&f)))    {   std::cerr << "equal\n";    }    else    {   std::cerr << "unequal\n";    }    return 0;}PS: sorry for triple post   ;  How do you plan to use this container?For example, what happens when I bind void(int,int) and void(double) and void(Foo *) into same container, then ask it to fire int(string &)?   ;Quote:Original post by AntheusHow do you plan to use this container?For example, what happens when I bind void(int,int) and void(double) and void(Foo *) into same container, then ask it to fire int(string &)?Yes, so you can bind multiple functions but you have to specify their parameters. So for a void(int, int) you'd have to pass also the 2 integers. These will all be stored in a derived version of Base.Then, when the owner of the container calls emit(), it will invoke all functions stored and pass their parameters. This is all 100% type safe as far as I have it now.Since I want to allow multiple amounts of parameters (up to 9), and C++ doesn't yet have variable template parameters, I had to resort to a FAT amount of macro "abuse", which generates code for all 9 classes to hold a function pointer (and also classes for (const) member function pointer).So the only problem I am having is selecting container elements based on partial template type information.   