Помогите мне с этим выражением boost :: lambda :: if_then, вызывающим функтор - PullRequest
2 голосов
/ 29 ноября 2010

Пожалуйста, посмотрите на следующий упрощенный пример:

#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)’

Любые подсказки, что не так с этим кодом?

Предполагается вызвать функтор Printer для любого элемента с item.soll == item.ist.

Спасибо за любую помощь!

Ответы [ 3 ]

2 голосов
/ 29 ноября 2010

ronag верен, лямбда-ссылка boost упоминает, что «Все они принимают лямбда-функторы в качестве параметров и возвращают void.»

Кажется, что альтернативный синтаксис (bl::if_(condition)[function]) нетребуют лямбда-функторы.

Однако, еще одна большая проблема заключается в том, что for_each возвращает функтор, который является форсированным лямбда-объектом, а не вашим принтером.Поэтому у вас все равно не будет возможности извлечь накопленную строку.

Вы можете заставить ее работать с чем-то вроде этого:

#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 голос
/ 29 ноября 2010

Правильные ответы уже предоставлены.Просто предлагая альтернативу, которая не включает 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)
    ]
);
1 голос
/ 29 ноября 2010

Попробуйте:

 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...