2014-04-18 70 views
0

這是針對無效()函數子,但我都沒...C++弱仿函數的解決方案

struct Foo 
{ 
    void Bar(int x) 
    { 
     std::cout << x << std::endl; 
    } 
}; 

struct VoidBind 
{ 
    typedef void result_type; 

    template<typename T> void operator()(const std::weak_ptr<T>& obj, std::function<void()>& func) 
    { 
     std::shared_ptr<T> shared_obj = obj.lock(); 

     if (shared_obj) 
     { 
      func(); 
     } 
    } 

    template<typename T> static std::function<void()> bind(const std::shared_ptr<T>& obj, const std::function<void()>& func) 
    { 
     return std::bind(VoidBind(), std::weak_ptr<T>(obj), func); 
    } 
}; 

#define BIND(F, O, A...) VoidBind::bind(O, std::function<void()>(std::bind(F, O.get(), ##A))) 

那麼這段代碼被調用爲...

auto obj = std::make_shared<Foo>(); 
auto func = BIND(&Foo::Bar, obj, 99); // match std::bind style 
func(); 
obj.reset(); // destroy object 
func();  // will not do anything 

我的問題是否有某種方法可以避免BIND宏?

回答

0

可變參數模板可以用在這裏:

template<class F, class O, class... Args> 
auto bind(F f, O&& o, Args&&... args) 
    -> decltype(VoidBind::bind(o, std::function<void()>(std::bind(f, O.get(), args...)))) 
{ 
    return VoidBind::bind(O, std::function<void()>(std::bind(F, O.get(), args...))); 
} 

它得到與C++ 14自動返回類型推演更好,你甚至不需要指定返回值:

template<class F, class O, class... Args> 
auto bind(F f, O&& o, Args&&... args) 
{ 
    return VoidBind::bind(o, std::function<void()>(std::bind(f, O.get(), args...))); 
} 
+0

這是有效的。謝謝。 – user1715664

0

您是否考慮過使用lambda表達式而不是函數對象 - 相同的功能,但更緊湊,並且將綁定作爲該lambda聲明的一部分。

+0

不幸的是,我必須使用的G ++版本不支持lambda表達式。 – user1715664