2016-09-27 71 views
0

可变参数模板假设我有一类具有一定数量的方法:处理方法,结果

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...); 
    ... 
} 

回答

0

看来,一个简单的功能做的伎俩:

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

,并调用它:

NotifyOnSuccess(foo.someMethodA(42, 5.1, 69)); 
NotifyOnSuccess(foo.someMethodB(5.1)); 
0
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

1

模板需要稍微充实,但你在正确的轨道上:

#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; 
}