Type of reflection in C ++

I am trying to implement a limited reflection in C ++ so that I can call getter and setter on stored objects. Here is what I have done so far

Main code

 #ifndef REFLECTION_MANAGER_HPP_ #define REFLECTION_MANAGER_HPP_ #include <iostream> #include <string> template <class Owner, class IOType> class SingleProperty { public: typedef IOType (Owner::*get_func_t)(); typedef void (Owner::*set_func_t)( IOType Value ); inline SingleProperty(get_func_t Getter, set_func_t Setter ): m_Getter(Getter), m_Setter(Setter) { } get_func_t m_Getter; set_func_t m_Setter; }; class ReflectionManager { public: static ReflectionManager& Instance() { static ReflectionManager instance; return instance; } template <class Owner, class IOType> void RegisterProperty( std::string class_name, std::string property_name, typename SingleProperty<Owner, IOType>::get_func_t GetFn, typename SingleProperty<Owner, IOType>::set_func_t SetFn) { SingleProperty<Owner, IOType>* pProperty = new SingleProperty<Owner, IOType>(GetFn, SetFn ); m_class_memeber_map[class_name][property_name] = pProperty; } template <class Owner> void put(std::string key, void *value, std::string class_name = NULL ) { Owner *ptr = reinterpret_cast<Owner*>(value); std::map<std::string, std::map< std::string, void*> >::iterator pos = m_class_memeber_map.find(class_name); if ( pos == m_class_memeber_map.end()) { return; // handle the error } for ( std::map< std::string, void*>::iterator itr = pos->second.begin(); itr != pos->second.end(); ++itr ) { SingleProperty<Owner,std::string> *ptr = (SingleProperty<Owner,std::string> *)itr->second; (ptr->*m_Getter)(); } } private: ReflectionManager() { } ReflectionManager(ReflectionManager const&); void operator=(ReflectionManager const&); std::map<std::string, std::map< std::string, void*> > m_class_memeber_map; }; #endif 

Call code

It will be called as follows

 ReflectionManager::Instance().RegisterProperty<Person, std::string>("Person", "m_name", &Person::GetName, &Person::SetName); ReflectionManager::Instance().RegisterProperty<Person, std::string>("Person", "m_dept", &Person::GetDept, &Person::SetDept); ReflectionManager::Instance().RegisterProperty<Person, int>("Person", "m_age", &Person::GetAge, &Person::SetAge); Person p1; p1.SetName("Avinash"); p1.SetDept("Gemfire Native Client"); p1.SetAge(34); ReflectionManager::Instance().put<Person>( "key1", &p1, "Person"); 

I saved getter and setter in map , but in put function that I cannot name, since I do not know the type.

Problem

Basically How to implement now the for for ( std::map< std::string, void*>::iterator itr = pos->second.begin(); itr != pos->second.end(); ++itr ) loop for ( std::map< std::string, void*>::iterator itr = pos->second.begin(); itr != pos->second.end(); ++itr ) , in which I want to for ( std::map< std::string, void*>::iterator itr = pos->second.begin(); itr != pos->second.end(); ++itr ) over each element and call the corresponding getter and setter methods.

I tried this but did not work.

 (ptr->*((itr->second).m_Getter))(); 

Another approach I found will be appreciated Comments

  template <class Owner, class IOType> void RegisterProperty( std::string class_name, std::string property_name, typename SingleProperty<Owner, IOType>::get_func_t GetFn, typename SingleProperty<Owner, IOType>::set_func_t SetFn) { SingleProperty<Owner, IOType>* pProperty = new SingleProperty<Owner, IOType>(GetFn, SetFn ); m_class_memeber_map[class_name][property_name] = pProperty; m_property_type_map[class_name].push_back(std::make_pair(property_name, TypeName<IOType>::get())); } template <class Owner> void put(std::string key, void *value, std::string class_name = NULL ) { Owner *pOwner = reinterpret_cast<Owner*>(value); std::map<std::string, std::map< std::string, void*> >::iterator pos = m_class_memeber_map.find(class_name); std::vector<std::pair<std::string, std::string> > vector_property_map = m_property_type_map.find(class_name)->second; for ( std::vector<std::pair<std::string, std::string> >::iterator itr = vector_property_map.begin();itr != vector_property_map.end(); ++itr ) { std::map< std::string, void*>::iterator pos_getter_setter_fn = pos->second.find(itr->first); if ( itr->second == "int" ) { SingleProperty<Owner,int> *ptr = (SingleProperty<Owner, int> *)pos_getter_setter_fn->second; (pOwner->*(ptr->m_Getter))(); } else if ( itr->second == "string" ) { SingleProperty<Owner,std::string> *ptr = (SingleProperty<Owner, std::string> *)pos_getter_setter_fn->second; (pOwner->*(ptr->m_Getter))(); } } } 
+4
source share
1 answer

These pointers are pointers to member functions of type Owner :

 get_func_t m_Getter; set_func_t m_Setter; 

Why are you trying to call them SingleProperty<> pointers as an object?

 Owner *ptr = reinterpret_cast<Owner*>(value); for ( std::map< std::string, void*>::iterator itr = pos->second.begin(); itr != pos->second.end(); ++itr ) { SingleProperty<Owner,std::string> *ptr = (SingleProperty<Owner,std::string> *)itr->second; // Here is the flaw, you are trying to call m_Getter from SingleProperty object // pointer, but it must be Owner pointer! (ptr->*m_Getter)(); } 

You also need to pass the property type correctly as an IOType template IOType . I'm not sure what you are trying to do with this function, and what is the effect of calling getters with a dropped return type, but from an abstract syntax point of view it will look like this:

 template <class Owner, class IOType> void put(const std::string& key, Owner* value, const std::string& class_name = "") { std::map<std::string, std::map<std::string, void*> >::iterator pos = m_class_memeber_map.find(class_name); if(pos == m_class_memeber_map.end()) { return; // handle the error } for(std::map<std::string, void*>::iterator itr = pos->second.begin(); itr != pos->second.end(); ++itr) { SingleProperty<Owner,IOType> *ptr = static_cast<SingleProperty<Owner, IOType>*>(itr->second); (value->*(ptr->m_Getter))(); // return IOType discarded?!?! } } 
+1
source

Source: https://habr.com/ru/post/1443405/


All Articles