C ++ Working with Template Objects

I have a class

class BarBase { }; 

and a derived template class that stores a pointer to a member function and a pointer to an object of the same class

 template<typename TypeName> class Bar: public BarBase { void ( TypeName::*action ) ( void ); TypeName* object; }; 

I create Bar instances and store pointers in them in the vector of another Foo class

 class Foo { private: vector<BarBase*> myBars; ... }; 

Now to the question. Foo has a template function

 template <typename TypeName> void Foo::foo( TypeName* object , void ( TypeName::*action ) ( void ) ) 

In this function, how to find elements in myBars with fields object and action equal to the parameters of this function? As you can see, I cannot directly access fields like this->myBars[i]->action , since these fields are not (and cannot be) members of BarBase .

EDIT I can compare object . I add virtual size_t getObject (){}; in BarBase and redefine it in Bar as virtual size_t getObject (){ return (size_t)this->object; }; virtual size_t getObject (){ return (size_t)this->object; }; . Then I compare the two size_t , but I do not know how to convert action to number ...

+4
source share
2 answers

The simplest solution is to make the base class polymorphic and use dynamic_cast to determine if it has the expected type:

 class BarBase { public: virtual ~BarBase() {} // virtual function required for polymorphism }; Bar<TypeName>* bar = dynamic_cast<Bar<TypeName>*>(myBars[i]); if (bar && bar->object == object && bar->action == action) { // it a match } 

This adds some overhead to RTTI support; from the top of my head, I can’t come up with any clearly defined way to do this so as not to add overhead.

+2
source

You can use something like this if you don't want to use the Mike variant (I prefer its variant).

 class BarBase { public: virtual ~BarBase() { } virtual void* getObject() { return 0; } virtual const char* getFunctionName() { return 0; } }; template<typename T> class Bar : public BarBase { public: Bar(T* obj, void (T::*func) (void)):object(obj), action(func) { } virtual void* getObject() { return object; } virtual const char* getFunctionName() { return typeid(action).name(); } T* object; void (T::*action)(void); }; 

http://liveworkspace.org/code/d79e33d4597ee209645026b2100330f3

EDIT.

Unfortunately. This is not a solution, as typeid(&S::action).name() may be equal to typeid(&S::other_action).name() .

In addition, you may not use dynamic_cast or static_cast for all objects in the vector.

 class BarBase { public: virtual ~BarBase() { } virtual void* getObject() const { return 0; } }; template<typename T> class Bar : public BarBase { public: Bar(T* obj, void (T::*func) (void)):object(obj), action(func) { } virtual void* getObject() const { return object; } T* object; void (T::*action)(void); }; for (auto pos = objects.begin(); pos != objects.end(); ++pos) { if ((*pos)->getObject() == &p) { auto bar = static_cast<Bar<S>*>(*pos); if (bar->action == act) { // right object founded. } } } 

http://liveworkspace.org/code/87473a94411997914906c22ef0c31ace

+1
source

All Articles