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

dar*_*une 3 c++ templates member-function-pointers variadic-templates c++17

我有一个接口,我必须在其中传递成员函数指针,这些指针被静态转换为基指针,并在我们的背后存储为 void 指针和调用类型( 消息表)。

我创建了一个包装器来执行一些异常处理(非常简单的 try/catch 来捕获 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
        }
      }
};
Run Code Online (Sandbox Code Playgroud)

但是为了避免对每种类型的调用进行显式重载 - 是否可以对参数列表进行参数化?

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

      template<void (MyClass::*f)(Args...)>
      void Dispatch(Args... args) {
Run Code Online (Sandbox Code Playgroud)

Joe*_*lho 5

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

template<auto f, typename... Args>
      void Dispatch(Args... args) {
      //...
Run Code Online (Sandbox Code Playgroud)

并通过将指向成员函数的指针作为模板参数 #1 传递来正常调用它们。现场示例

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

还有一件小事:如果您使用的是右值语义,那么接收Args&&和使用std::forward.