I was trying to write a general purpose method locking wrapper for operations around a list. What I currently have is:
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...);
}
And, I can use it like this:
auto push_back = [this](decltype(p) p) {
return list_.push_back(p); };
locked_call(push_back, p);
But, I would rather be able to pass the method to be called directly into locked_call and it dispatch directly against 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...);
}
I realized quickly this is tricky because of method overloading, and research seems to indicate explicitly resolving the overload is required. Is there any clever use of templates or decltype I can use to allow the code to simply pass the method name into locked_call?
As a hack, I can use a macro to achieve the simplified syntax by autogenerating a lambda:
#define LOCKED_CALL(METHOD, ...) \
locked_call([this,##__VA_ARGS__](){ \
return list_.METHOD(__VA_ARGS__); })
But I was hoping there was a template equivalent.
Aucun commentaire:
Enregistrer un commentaire