Я начну с прямого ответа, но, пожалуйста, прочитайте следующее предупреждение:
Более простой синтаксис того, что вы пытаетесь сделать, будет включать изменение типа третьего параметра на wrapper()
.Вместо преобразования функций-членов в функции, не являющиеся членами, просто возьмите функцию-член в качестве параметра.
void wrapper(int id, void* arg, void (Entity::* func)(int,void*))
{
cout <<"\nSome Other critical task based on id"<< endl;
(this->*func)(id, arg);
}
Тогда ваши вызовы станут проще:
wrapper(1, static_cast<void*>(&name), &Entity::getUserName);
wrapper(1, static_cast<void*>(&name), &Entity::setUserName);
Однако это действительно подход, который вы хотите использовать?Вы полагаетесь на людей, которые не забывают вызывать оболочку, а не напрямую вызывать другие функции-члены.Если вы забудете использовать оболочку в какой-то момент, сможете ли вы отследить причину, основываясь на симптомах?Вы даже хотите попробовать?
Более надежный подход заключается в том, чтобы поместить критическую задачу в ее собственную функцию, а затем вызвать ее для методов получения и установки.Нечто подобное:
void criticalStuff(int id)
{
cout <<"Some critical task based on id\n";
}
void Entity::getUserName(int id, string & arg)
{
criticalStuff(id); // Critical stuff first.
auto iter = userMap.find(id);
if(iter != userMap.end()) {
arg = iter->second.name;
}
}
void Entity::setUserName(int id, const string & arg)
{
criticalStuff(id); // Critical stuff first.
auto iter = userMap.find(id);
if(iter != userMap.end()) {
iter->second.name = arg;
}
}
Любой, кто добавляет новые поля, все равно должен помнить критические вещи при написании новых методов получения и установки, но более распространенный случай (вызов этих функций) будет обрабатывать критические вещи автоматически.Кроме того, вы можете вернуться к проверке типов параметров, поскольку больше нет причин приводить вещи к void *
.