I have provided a simpler version of the problem, that I am dealing with.
I have class Entity, which has a map of a user object. For simplicity, I have added only one element(name). I have implemented getter and setter around the userMap object.
The wrapper function is required for me, to handle a critical situation because of a multi-threaded case. (not shown here). I have somehow implemented a working example by going through a few SO threads.
But as you can see, I have to write (id,arg) tuple argument in three places while using wrapper function inside procedure function. Is there a way of implementing the same functionality by having some kind of placeholder for the function arguments so that calling the wrapper looks clean, i.e. wrapper(1,static_cast<void*>(&name),function_ptr).
#include <iostream>
#include <functional>
#include <map>
using namespace std;
class Entity {
public:
struct user {
int id;
string name;
};
map<int,user> userMap;
void getUserName(int id,void * arg);
void setUserName(int id,void * arg);
void procedure();
void wrapper(int id,void*,std::function<void(int,void*)>);
};
void Entity::getUserName(int id,void *arg) {
auto iter = userMap.find(id);
if(iter != userMap.end()) {
*static_cast<string*>(arg) = iter->second.name;
}
}
void Entity::setUserName(int id,void *arg) {
auto iter = userMap.find(id);
if(iter != userMap.end()) {
iter->second.name = *static_cast<string*>(arg);
}
}
void Entity::wrapper(int id,void *arg,std::function<void(int,void*)> func) {
cout <<"\nSome Other critical task based on id"<< endl;
// then call the callback
func(id,arg);
}
void Entity::procedure() {
cout <<"Procedure starts"<<endl;
user u = {};
u.id = 1;
u.name = "abc";
this->userMap[1] = u;
string name;
wrapper(1,static_cast<void*>(&name),[this](int id,void*arg){
getUserName(id,arg);
});
cout <<"name :"<< name << endl;
cout <<"\nSome processing..."<<endl;
name = "def";
wrapper(1,static_cast<void*>(&name),[this](int id,void*arg){
setUserName(id,arg);
});
cout <<"\nSome more processing..."<<endl;
wrapper(1,static_cast<void*>(&name),[this](int id,void*arg){
getUserName(id,arg);
});
cout <<"name :"<< name << endl;
cout <<"Procedure ends"<<endl;
}
int main() {
Entity E;
E.procedure();
}
Output:
Some Other critical task based on id
name :abc
Some processing...
Some Other critical task based on id
Some more processing...
Some Other critical task based on id
name :def
Procedure ends
Thanks!
Aucun commentaire:
Enregistrer un commentaire