其他成员函数的通用“成员函数”包装器?

时间:2019-09-09 09:41:00

标签: c++ templates c++17 variadic-templates member-function-pointers

我有一个接口,必须 传递成员函数指针,这些成员函数指针被静态转换为基本指针,并在我们的背后存储为void指针和调用类型({{3} }

我创建了一个包装程序,该包装程序执行一些异常处理(非常简单地尝试/捕获以捕获std :: runtime_error),因为这很繁琐且易于在每个用户回调中维护。

到目前为止,以下包装器实际上工作得很好(其思想是直接将成员函数指针作为值模板参数获取-本质上为每个成员提供一个成员函数包装器回调函数。):

class MyClass : public CWnd/*example*/{
public:
      template<void (MyClass::*f)(CCmdUI*)>
      void Dispatch(CCmdUI* pCmdUI) {
        try {
          (this->*f)(pCmdUI);
        }
        catch (std::runtime_error& e) {
          //handle error
        }
      }
};

但是为了避免每种调用都显式过载-是否可以将参数列表参数化?

插图(请注意,这不起作用):

      template<void (MyClass::*f)(Args...)>
      void Dispatch(Args... args) {

1 个答案:

答案 0 :(得分:4)

由于您使用的是C ++ 17,因此可以在模板参数上使用auto

template<auto f, typename... Args>
      void Dispatch(Args... args) {
      //...

并通过将指向成员函数的指针作为模板参数#1正常调用它们。 Live Example

如果您需要检查f是否是该类成员函数的指针,则可以在调用static_assert之前使用一些(this->*f)(args...)语句。

一件小事:如果您正在使用右值语义,那么接收Args&&并使用std::forward也是一个好主意。