2012-03-08 5 views
0

을 사용하여 boost::unoredered_map에 새로운 키 - 값 쌍을 삽입하는 boost::function을 만들고 싶지만 컴파일 오류가 거의 없습니다.boost :: bind 및 boost :: unordered_map의 삽입

typedef boost::unordered_map< 
     std::string, std::string > dict_type; 


inline void insert(const std::string& key, const std::string& value){ 

    typedef std::pair<dict_type::iterator, bool> out_type; 

    dict_type::value_type to_insert(key,value); 

    boost::function<void()> f = boost::bind<out_type>( 
     &dict_type::insert 
     ,obj_ 
     ,boost::cref(to_insert) 
    ); 
} 

오류는 아래 unordered_map::insert에 적합한 과부하를 찾을 수 없습니다 bind 것 같습니다. 이 경우 정확한 오버로드를 지정하지만 이번에는 작동하지 않습니다. 그게 뭔지 아십니까?

../include2/llve_clorder_id.h:32: error: no matching function for call to 
'bind(<unresolved overloaded function type>, 
boost::unordered_map<std::basic_string<char, std::char_traits<char>, 
std::allocator<char> >, std::basic_string<char, std::char_traits<char>, 
std::allocator<char> >, boost::hash<std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, 
std::char_traits<char>, std::allocator<char> >, std::basic_string<char, 
std::char_traits<char>, std::allocator<char> > > > >&, const 
boost::reference_wrapper<const std::pair<const std::basic_string<char, 
std::char_traits<char>, std::allocator<char> >, std::basic_string<char, 
std::char_traits<char>, std::allocator<char> > > >)' 
+0

컴파일러 버전을 지정할 수 있습니까? 부분 특수화를 이해하지 못하는 일부 오래된 컴파일러는'boost :: bind'에 대한 첫 번째 인수로 함수 멤버에 대한 포인터를 받아 들일 수 없습니다. –

답변

1

문제는 boost::unordered_map 하나 이상의 insert가 포함되어 있습니다 : 임시 변수를 사용하여 완전히 읽을되고 중지, 그것과 같을 것이다. 가장 간단한 해결책은 올바른 오버로드를 호출하는 함수를 정의하는 것입니다 :

void insert(dict_type & dict, dict_type::value_type const & value) { 
    dict.insert(value); 
} 

boost::function<void()> f = boost::bind( 
    insert 
    ,boost::ref(obj_) 
    ,boost::cref(to_insert) 
); 

또는 명시 적으로 과부하 지정할 수 있습니다 : 당신이 람다와 함께 문제를 방지 할 수 있습니다, C++ 11에서

boost::function<void()> f = boost::bind( 
    static_cast<out_type (dict_type::*)(dict_type::value_type const &)>(&dict_type::insert) 
    ,obj_ 
    ,boost::cref(to_insert) 
); 

을 :

std::function<void()> f = [&](){obj_.insert(to_insert);}; 
+0

나는 당신의 솔루션이 static_cast <>를 사용한다고 잘못 말하는 것이 더 빠릅니까? static_cast <>를 사용하면 모호성이 컴파일 타임에 해결되므로 쓰기가 더 길더라도 더 빨리 바인딩 할 수 있습니다. –

+0

이론적으로'static_cast'는 더 빠를 것입니다 (예제와 같습니다). 그러나 일부 컴파일러는 사소한 기능을 최적화 할 수 있기 때문에 같은 결과를 내고 있습니다. –

+0

Auch..I 찾았습니다. 두 번째 인수로 & obj가 있어야합니다. –

1

http://www.boost.org/doc/libs/1_49_0/libs/bind/bind.html#Troubleshooting는 때때로 원하는 형식에 포인터 멤버 함수를 주조에 의해 오버로드 기능을 가진 문제를 해결할 수 있음을 시사한다. 그래서 &dict_type::insert가 모호,

typedef std::pair<typename dict_type::iterator, bool> out_type; 

typename dict_type::value_type to_insert(key,value); 

out_type (dict_type::*ins) (typename dict_type::value_type const&) const = &dict_type::insert; 

boost::function<void()> f = boost::bind(
    ins 
    ,obj_ 
    ,boost::cref(to_insert) 
); 
+0

안녕 Dan. 나는 당신이 제안하고있는 페이지를 읽고 지금은 왜 바인드 가 작동하지 않았는 지 잘 이해하고 있습니다. 고마워. –