Я пытался написать оболочку блокировки метода общего назначения для операций со списком.Сейчас у меня есть:
template <typename OP, typename... ARGS>
auto locked_call (OP op, ARGS... args) const
-> decltype(op(args...)) {
std::lock_guard<std::mutex> g(lock_);
return op(args...);
}
И я могу использовать это так:
auto push_back = [this](decltype(p) p) {
return list_.push_back(p); };
locked_call(push_back, p);
Попробуйте онлайн!
НоЯ предпочел бы передать метод, который будет вызван непосредственно, в locked_call
, и он будет отправлен непосредственно против list_
.
template <typename METHOD, typename... ARGS>
auto locked_call (METHOD op, ARGS... args) const
-> decltype((list_.*op)(args...)) {
std::lock_guard<std::mutex> g(lock_);
return (list_.*op)(args...);
}
Я быстро понял, что это сложно из-за перегрузки метода, и исследование кажетсядля явного разрешения проблемы необходима перегрузка.
locked_call(static_cast<void (List::*)(const int &)>(&List::push_back), p);
Попробуйте онлайн!
Есть ли какое-либо умное использование шаблонов или decltype
, которые я могу использовать, чтобы разрешитькод для простой передачи имени метода в locked_call
?
В качестве хака я могу использовать макрос для достижения упрощенного синтаксиса, автоматически генерируя лямбду:
#define LOCKED_CALL(METHOD, ...) \
locked_call([this,##__VA_ARGS__](){ \
return list_.METHOD(__VA_ARGS__); })
Но я надеялся, что найдется шаблонный эквивалент.