2014-04-18 4 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

펑터 객체 대신 람다 표현식을 사용하는 것을 고려 했습니까? 동일한 기능이지만 훨씬 작고 람다 선언의 일부로 바인드를 사용하십시오.

+0

을 불행히도 G ++ 버전은 람다 식을 지원하지 않습니다. – user1715664