我有一个接口,必须 传递成员函数指针,这些成员函数指针被静态转换为基本指针,并在我们的背后存储为void指针和调用类型({{3} } mfc。
我创建了一个包装程序,该包装程序执行一些异常处理(非常简单地尝试/捕获以捕获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) {
答案 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
也是一个好主意。