2016-10-14 9 views
1

나는 입력으로 boost::function<> 유형의 객체를 취하고 다른 물류를 처리하는 다른 함수로 함수를 래핑하는 도우미 메서드가 있습니다. 여기 boost :: bind의 결과 인 매개 변수를 취하는 템플릿 함수를 만들려면 어떻게해야합니까?

이처럼 내 서명이 모습입니다 : 내가 boost::bind 인라인을 호출 한 결과를 make_wrapper 통과하려고하면 내가 유형이 호환되지 않는 것에 대해 컴파일 에러가 발생

class Example { 
public: 
    typedef ... Callback; 

    ... 

    template<typename T> 
    static Callback make_wrapper(const boost::function<void(T)>&); 
}; 

(애플 LLVM 버전 7.3.0)

class OtherClass { 
public: 
    void method (uint32_t); 
}; 

OtherClass* other; 

Example::Callback c = Example::make_wrapper (boost::bind(&OtherClass::method, other, _1)); 

이 제공 :

error: no matching function for call to 'make_wrapper' 
note: candidate template ignored: could not match 'function' against 'bind_t' 

나는 F를 운드,이 약 2 가지 방법 :

  1. 온도 변수 : make_wrapper의

    boost::function<void(uint32_t)> f = boost::bind(&OtherClass::method, other, _1); 
    Example::Callback c = Example::make_wrapper (f); 
    
  2. 전화 특정 전문화 : 나는를 건너 뛸 수 있다면

    Example::Callback c = Example::make_wrapper<uint32_t> (boost::bind(&OtherClass::method, other, _1)); 
    

내가 많이 선호 여분의 힌팅과 바인딩 인라인 호출과 함께 make_wrapper를 호출하십시오.

컴파일러가 위의 해결 방법 중 하나를 사용하지 않고 유형을 파악하는 데 도움이되는 make_wrapper 템플릿의 서명을 선언 할 수있는 방법이 있습니까?

+0

'자동'또는 'decltype'을 사용하십시오. – Zereges

답변

1

bind을 사용할 때마다 바인딩 된 함수의 매개 변수 유형에 대한 모든 정보가 삭제됩니다. 함수 템플리트는 매개 변수 유형 T을 추론 할 수 없습니다. bind의 리턴 값은 모든 유형의 매개 변수 수에 관계없이 호출 할 수있는 함수 오브젝트입니다.

당신은 바인딩 된 멤버 함수와 특히 결과 유형 및 매개 변수 (예 std::bindstd::function 사용하지만 쉽게 boost로 변환 할 수 있다고 생각) 추론 할 도우미 함수 템플릿에 bind 기능을 래핑 수 :

#include <iostream> 
#include <string> 
#include <functional> 

struct foo { 
    void bar(int a, std::string s) { 
    std::cout << a << " " << s << std::endl; 
    } 
}; 


template<typename T1, typename T2> 
void make_wrapper(const std::function<void(T1, T2)>&) { 
} 

template <class Foo, class Res, class... Args, class... Placeholders> 
std::function<Res(Args...)> my_bind(Res (Foo::*bar)(Args...), Foo& f, Placeholders... ps) { 
    return std::bind(bar, f, ps...); 
} 

int main() { 
    foo f; 
    make_wrapper(my_bind(&foo::bar, f, std::placeholders::_1, std::placeholders::_2)); 
} 

foo::bar이 오버로드되지 않는 한 코드는 작동하지만 static_cast은 피할 수 없습니다.

0

std::bindboost::bind 모두 반환 유형을 지정되지 않은 것으로 표시합니다. 이것은 당신이 모든 휴대용에 있기를 원한다면, 당신이 그것을 알 수 없다는 것을 의미합니다.