2010-04-30 2 views
1

lambda :: bind를 통해 멤버를 호출하고 싶습니다. 불행히도 같은 이름을 가진 두 멤버가 있지만 반환 유형이 다릅니다. 멤버 함수 호출에 대해 올바른 반환 형식을 추론하도록 lambda :: bind를 도와주는 방법이 있습니까? 문서boost lambda :: bind 반환 유형 선택

를 들어

#include <vector> 
#include <iostream> 
#include <algorithm> 
#include <boost/bind.hpp> 
#include <boost/lambda/lambda.hpp> 
#include <boost/lambda/bind.hpp> 

using namespace std; 
using namespace boost; 

struct A 
{ 
    A (const string & name) : m_name(name) {} 

    string &  name()   { return m_name; } 
    const string & name() const { return m_name; } 

    string m_name; 
}; 

vector<A> av; 

int main() 
{ 
    av.push_back (A ("some name")); 

    // compiles fine 
    find_if(av.begin(), av.end(), bind<const string &>(&A::name, _1) == "some name"); 

    // error: call of overloaded 'bind(<unresolved overloaded function type>, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >&)' is ambiguous 
    find_if(av.begin(), av.end(), lambda::bind(&A::name, lambda::_1) == "some name"); 

    return 0; 
} 

답변

1

다른 반환 유형은 빨간색 청어입니다. 문제는 메소드의 const 오버로드 (즉, 상대적인 반환 유형이 무엇이든 상관없이 동일한 문제가 발생합니다) 때문입니다. 이 문제는 herehere이며 반환 유형 지정 양식은 not the recommended solution입니다 (일부 버전의 MSVC 제외).

문제는 오버로드 된 멤버 함수 (const 오버로드 또는 매개 변수 오버로드)의 주소를 가져 오는 것이 모호하므로 일부 추가 정보가 필요하다는 것입니다.

해결 방법은 컴파일러가 원하는 오버로드 된 함수를 정확히 알 수 있도록 함수 포인터를 캐스팅하는 것입니다. 가장 확실한 방법은 함수 포인터 유형을 typedef하는 것입니다. 조금 불쾌한. 여기에 (깨끗한 GCC 4.3.4 컴파일) 코드와 예제입니다 : 당신은 그냥 진짜 문제 : 가 반환 람다 입력 : 부스트를 오버라이드 (override) 할 수있는 방법이 있지만 지적했다

#include <vector> 
#include <iostream> 
#include <algorithm> 
#include <boost/bind.hpp> 
#include <boost/lambda/lambda.hpp> 
#include <boost/lambda/bind.hpp> 

using namespace std; 
using namespace boost; 

struct A 
{ 
    A (const string & name) : m_name(name) {} 

    string &  name()   { return m_name; } 
    const string & name() const { return m_name; } 

    string m_name; 
}; 

vector<A> av; 

//function pointer for non-const version 
typedef string& (A::*NameFuncType)(void); 

//function pointer for const version 
typedef const string& (A::*NameConstFuncType)(void) const; 

int main() 
{ 
    av.push_back (A ("some name")); 

    //'correct' way to call const version w/ boost::bind 
    find_if(av.begin(), av.end(), 
    bind(static_cast<NameConstFuncType>(&A::name), _1) == "some name" 
); 

    //call for non-const version w/ boost::lambda::bind 
    find_if(av.begin(), av.end(), 
    lambda::bind(static_cast<NameFuncType>(&A::name), lambda::_1) == "some name" 
); 

    return 0; 
} 
1

(바인드는 명시 적 반환 형식 공제와 함께 잘 작동) "바인드 발현에 의해 생성 된 λ 펑터의 반환 형식은 같이 명시 적으로 지정된 템플릿 매개 변수로 제공 할 수있다 예를 들어 다음

바인드 (대상 기능, 바인드 인수 목록) "

그래서 당신이 부스트와 함께했던 같은 일을 : 바인딩.

find_if(av.begin(), av.end(), lambda::bind<const string &>(&A::name, lambda::_1) == "some name"); 

P. 테스트하지 않았습니다

+0

그것을 유일한 작품 바인드가 아닌 람다 표현식. 참조 : lambda :: ret (e) 참조. 불행히도 현재 상황에서는 적용 할 수 없습니다 ... – psaghelyi