2013-12-12 2 views
0

을 사용하여 map의 키를 모두 다른 것으로 복사하려고합니다.bind 및 make_pair로 해결되지 않은 오버로드

나는 내 코드 아래

error: no matching function for call to 
‘bind(<unresolved overloaded function type>, boost::arg<1>&, boost::arg<1>&)’ 

말을 컴파일 오류가 발생하고있다.

using namespace boost; 
map<string,int32_t> A; 

typedef map<string,string> BType; 
BType B; 

std::for_each(A.begin(), A.end(), 
     bind(&BType::insert,&B,bind(&std::make_pair,_1,_1))); 

무엇이 잘못 되었습니까?

+0

시도'표준 : make_pair <문자열, 문자열>' – Raxvan

+0

하고'귀하의 경우 _1'는'표준으로,이 함수 객체를 사용하여 적절한 std::bind() 표현, 즉 각 _1을 대체 할 것 :: –

+0

'std :: make_pair'를 변경 한 후,'bind' 호출은 함수 객체를'B'에 삽입하려고하는 nullary 함수 객체를 생성 할 것입니다. – Simple

답변

3

중요한 문제는 오버로드 집합의 주소를 사용할 수 없다는 것입니다. std::make_pair은 함수 템플릿이며 사용자가 이야기하는 인스턴스화를 나타내지 않습니다. 마찬가지로 std::map<K, V>::insert은 과부하가 걸립니다. 예를 들어 하나의 요소를 취하는 버전과 버전을 취하는 버전이 있습니다.

어떤 형식으로 오버로드 된 함수의 주소를 사용할 수 있다고하더라도 실제로 도움이 필요하면 실제로 원하지 않습니다. 그 이유는 함수 포인터 나 멤버 함수 포인터를 호출하는 것이 inline 함수를 호출하는 것보다 훨씬 비싸고 함수 포인터를 통해 호출하는 것이 인라인하기가 훨씬 어렵 기 때문입니다. 컴파일러는 특정 [구성원] 함수 포인터가 항상 참조한다는 것을 증명해야합니다 동일한 [멤버] 함수에 추가합니다.

두 가지 문제에 대한 해결책은 bind()에 적절한 함수에 단순히 위임 한 템플릿 함수 호출 연산자가있는 함수 개체를 지정하는 것입니다. 예를 들어 :

struct make_a_pair { 
    template <typename T0, typename T1> 
    std::pair<T0, T1> operator()(T0&& t0, T1&& t1) { 
     return std::make_pair(std::forward<T0>(t0), std::forward<T1>(t1)); 
    } 
}; 

C++ 03을 사용하면 T0 const&T1 const& 대신 T0&&T1&&을 사용하십시오 그리고 당신은 단지 대신 std::forward<>()를 사용하는 인자를 전달할 것입니다. C++ 11 환경에서는 아마도 decltype()을 사용하는 타입을 반환 할 것입니다. 삽입하기위한 유사한 함수 객체는 다음과 같이 수 :

struct inserter { 
    template <typename M, typename T> 
    void operator()(M* map, T&& value) { 
     map->insert(std::forward<T>(value)); 
    } 
}; 

를 장소에이 두 함수 객체로 당신은 당신의 bind() 식을 사용할 수 있습니다 : 나는 아주 쉽게이 문제를 테스트 할 수 없습니다 지금

std::for_each(A.begin(), A.end(), 
    boost::bind(inserter(), &B, boost::bind(make_a_pair(), _1, _1))); 

을하지만, _1_1 쌍이 원하는 것임을 가정하면, 그 라인을 따르는 것이 작동합니다.

struct project1st { 
    template <typename T0, typename T1> 
    typename std::remove_const<T0>::type 
    operator()(std::pair<T0, T1> const& p) const { 
     return p.first; 
    } 
}; 

이 기능 개체 : 다른 함수 객체를 사용하여, 당신은 정말 당신이 적절하게 예를 들어 원래지도의 키를 투영해야 할 것이 경우 키에 키에서 매핑을 만들 보인다 결과가 반환되기 전에 std::map<K, V> 쌍이있는 경우 해당 쌍이 std::pair<K const, V> 인 경우 첫 번째 T0에서 const을 제거합니다. 당신은

boost::bind(project1st(), _1) 
+0

남은 문제가 있습니다 : for_each도 쌍으로 작업 중입니다 ... 그래서'make_a_pair(), _1, _1'는 두 쌍의 string/int ... – Johan

+0

@Johan : 어, 네. 이를 해결하려면'_1'을 적절한 값으로 투영해야합니다. 나는 그 부분을 언급하면서 대답을 업데이트 할 것이다. –

관련 문제