用于处理方法结果的变分模板

Variadic template for processing method result

本文关键字:处理 方法 结果 用于      更新时间:2023-10-16

假设我有一个类有一些方法:

class Foo {
  bool someMethodA(int someParamA, double someParamB, int someParamC);
  bool someMethodB(double someParamA);
  bool someMethodC(double someParamA);
  ...
}

每个方法都有不同的签名。有没有一种方便的方法可以调用这些方法,以便在true(成功(时调用通知程序方法?

notifySuccess();

执行此操作的宏是:

// Call a function notifyAll() on success
#define NOTIFY_ON_SUCCESS(func) 
  bool success = func;          
  if (success) {                
    notifySuccess();            
  }                             
  return success;

有人建议有一种方法可以使用可变模板来实现这一点?类似于:

template <typename... ARGS>
bool CallImplAndNotify(bool (&SceneImpl::*func)(ARGS...), ARGS... args) {
   bool result = func(args...);
   ...
}

模板需要稍微充实一下,但您走在了正确的轨道上:

#include <type_traits>
#include <functional>
#include <iostream>
void notifySuccess()
{
    std::cout << "Success" << std::endl;
}
template <typename Obj, typename... ARGS,
      typename ...Params>
bool CallImplAndNotify(Obj &obj, bool (Obj::*func)(ARGS...),
               Params && ...params)
{
    if ((obj.*func)(std::forward<Params>(params)...))
    {
        notifySuccess();
        return true;
    }
    return false;
}
class Foo {
public:
    bool someMethodA(int someParamA, double someParamB, int someParamC)
    {
        return true;
    }
    bool someMethodB(double someParamA)
    {
        return false;
    }
    bool someMethodC(double someParamA)
    {
        return true;
    }
};
int main()
{
    Foo f;
    CallImplAndNotify(f, &Foo::someMethodA, 0, 1.0, 2.0);
    CallImplAndNotify(f, &Foo::someMethodB, 1.0);
    CallImplAndNotify(f, &Foo::someMethodC, 1.0);
    return 0;
}

似乎一个简单的函数就可以做到这一点:

bool NotifyOnSuccess(bool b) {
   if (b) {
       notifySuccess();
   }
   return b;
}

并称之为

NotifyOnSuccess(foo.someMethodA(42, 5.1, 69));
NotifyOnSuccess(foo.someMethodB(5.1));
template <class... Args, class...Ts>
bool CallImplAndNotify(bool (&SceneImpl::*func)(Args...), Ts&&... ts) {
   bool result = (this->*func)(std::forward<Ts>(ts)...);
   if(result) notify_on_success();
   return result;
 }

或者:

template<class T>struct tag_t{using type=T;};
template<class T>using block_deduction=typename tag_t<T>::type;
template <class... Args>
bool CallImplAndNotify(bool (&SceneImpl::*func)(Args...), block_deduction<Args>... args) {
   bool result = (this->*func)(std::forward<Args>(args)...);
   if(result) notify_on_success();
   return result;
}

第一种可能稍微更高效,第二种允许{}式构造并传递NULL令牌而不是nullptr