2010-11-29 2 views
2

는 다음과 같은 간단한 예에서 참조하시기 바랍니다 :이 부스트 : : 람다 좀 도와 :: if_then 표현을 펑터를 호출

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

using namespace boost::lambda; 
namespace bl = boost::lambda; 

using namespace std; 

struct Item 
{ 
    string sachNr; 
    int ist; 
    int soll; 
}; 

struct Printer 
{ 
    void operator()(const Item &item) 
    { 
     m_erg += item.sachNr; 
    } 

    operator string() 
    { 
     return m_erg; 
    } 

private: 

    string m_erg; 
}; 

void TestFunction() 
{ 
    vector<Item> pickItems; 

    string result = for_each(pickItems.begin(), pickItems.end(), 
     bl::if_then(bl::bind(&Item::ist, bl::_1) == bl::bind(&Item::soll, bl::_1), 
     Printer())); 
} 

ERRORMESSAGE (GCC)

/TestCpp-build-desktop/../TestCpp/ctest.cpp:52: error: no matching function for call to ‘if_then(const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::relational_action<boost::lambda::equal_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, boost::tuples::tuple<int Item::* const, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, boost::tuples::tuple<int Item::* const, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >, Printer)’ 

어떤 힌트 무엇을 잘못 그 코드?

item.soll == item.ist가있는 항목에 대해서는 Printer Functor를 호출해야합니다.

도움 주셔서 감사합니다.

+0

확실하지를하지만, 대체 문법 ('if_ (조건)을 시도 [기능]'또 다른 문제를 보여준다 : for_each를'에 펑를 '프린터 '가 아니라 람다 오브젝트를 지원하기 때문에 문자열 변환을 기대할 수 없습니다 - 이미 펑터를 작성 했으므로 좀 더 많은 작업을 할 수 없습니까? – visitor

+0

또는 BOOST_FOREACH를 사용하십시오 코드는 짧고, 평신도가 이해할 수 있고 일하기가 더 쉬울 것입니다. 'for_each'를 얻으려고 시도하는 것은 의미가 없습니다. – visitor

+0

예, BOOST_FOREACH와 작동하도록 변경했습니다. 그럼에도 불구하고 나는 그것을 끝내는 것에 흥미가있다. 위의 예제 코드 (항상 새로운 것을 배우려고) – nabulke

답변

2

ronag이 정확한지, 부스트의 람다 참조는 "그들은 모두 람다 펑터을 매개 변수로 사용하고 void를 반환합니다"라고 언급합니다.

대체 구문 (bl::if_(condition)[function])에는 람다 펑터가 필요하지 않은 것으로 보입니다.

그러나 또 다른 큰 문제는 for_each이 프린터가 아닌 부스트 lambda 객체 인 Functor를 반환한다는 것입니다. 따라서 어쨌든 누적 된 문자열을 검색 할 방법이 없습니다.

당신은이 같은 작업을 얻을 수 있습니다 : 그러나

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

using namespace boost::lambda; 
namespace bl = boost::lambda; 

using namespace std; 

struct Item 
{ 
    string sachNr; 
    int ist; 
    int soll; 
}; 

struct Printer 
{ 
    typedef void result_type; 
    void operator() (const Item &item, std::string& s) const 
    { 
     s += item.sachNr; 
    } 
}; 

void TestFunction() 
{ 
    vector<Item> pickItems; 

    string result; 
    for_each(pickItems.begin(), pickItems.end(), 
     bl::if_then(
      bl::bind(&Item::ist, bl::_1) == bl::bind(&Item::soll, bl::_1), 
      bl::bind(Printer(), bl::_1, boost::ref(result)) 
     ) 
    ); 
} 

,

void TestFunction() 
{ 
    vector<Item> pickItems; 
    string result; 
    BOOST_FOREACH(const Item& item, pickItems) { 
     if (item.ist == item.soll) 
      result += item.sachNr; 
    } 

} 

당신이 원하는 것을 얻기 위해 많은 간단하게 될 것입니다. for_each는 실제로 아무 것도 유용하지 않으므로 사소한 일만을 위해 사용하지 않을 것입니다.

1

이 시도 :

Printer printer; 
std::for_each(pickItems.begin(), pickItems.end(), bl::if_then(bl::bind(&Item::ist, bl::_1) == bl::bind(&Item::soll, bl::_1), bl::bind(&Printer::operator(), &printer, bl::_1))); 

이 BL :: if_then 어떤 펑을 허용하지 않는 날 것으로 보인다, 그것은 lambda_functor 할 필요가있다.

1

정답은 이미 제공되었습니다. 그냥 Printer 개체를 포함하지 않는 대안 제공 :이 특정 오류에 대한

std::string s; 
for_each(
    pickItems.begin(), pickItems.end(), 
    bl::if_ (bl::bind(&Item::ist, bl::_1) == bl::bind(&Item::soll, bl::_1)) 
    [ 
     s += bl::bind(&Item::sachNr, bl::_1) 
    ] 
); 
관련 문제