2010-11-29 5 views
2

Bitte werfen Sie einen Blick auf die folgenden vereinfachten Beispiel Aufruf:Helfen Sie mir mit diesem boost :: lambda :: if_then Ausdruck einen Funktor

#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())); 
} 

Fehlermeldung (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)’ 

Irgendwelche Hinweise, was falsch ist mit diesem Code?

Es soll den Drucker Funktor für jedes Element mit item.soll == item.ist aufrufen.

Danke für jede Hilfe!

+0

Nicht sicher über diese besondere Fehler, sondern versucht, die alternative Syntax ('IF_ (Bedingung) [Funktion]' zeigt ein weiteres Problem: die Funktors zu 'for_each '' '' '' '' Printer'' ist kein Boost-Lambda-Objekt, daher kann man nicht erwarten, dass die Konvertierung in eine Zeichenfolge trotzdem stattfindet. - Da Sie bereits einen Funktor geschrieben haben, warum nicht ein bisschen mehr Arbeit? – visitor

+0

Alternativ: mit BOOST_FOREACH , der Code wäre kürzer, für einen Laien verständlicher und einfacher zur Arbeit zu gelangen. IMO, es ist sinnlos zu versuchen, 'for_each' etwas zu tun, für das es kaum gedacht ist. – visitor

+0

Ja, ich habe es geändert, um mit BOOST_FOREACH zu arbeiten funktioniert gut, aber ich bin daran interessiert, es fertig zu machen mit dem obigen Beispielcode (immer versuchen, etwas Neues zu lernen) – nabulke

Antwort

2

RONAG ist korrekt, Boosts Lambda-Referenz erwähnt, dass "sie alle Lambda Funktoren als Parameter nehmen und void zurückgeben."

Es scheint, dass die alternative Syntax (bl::if_(condition)[function]) keine Lambda-Funktoren erfordert.

Ein weiteres großes Problem ist jedoch, dass for_each den Funktor zurückgibt, der ein Boost-Lambda-Objekt ist, nicht Ihr Drucker. Daher haben Sie keine Möglichkeit, die akkumulierte Zeichenfolge trotzdem abzurufen.

Sie könnten bekommen es mit so etwas wie dies funktioniert:

#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)) 
     ) 
    ); 
} 

jedoch

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

} 

wäre viel einfacher zu bekommen, was Sie wollen. for_each tut praktisch nichts nützliches, also würde ich nicht aus dem Weg gehen, es für nichts als triviale Dinge zu verwenden.

1

Try this:

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))); 

Es scheint mir, dass bl :: if_then nicht functor akzeptiert, braucht es eine lambda_functor zu sein.

1

Richtige Antworten wurden bereits zur Verfügung gestellt. Nur eine Alternative anbieten, die kein Printer Objekt mit sich bringt:

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) 
    ] 
); 
Verwandte Themen