帮我这个boost :: lambda :: if_then表达式调用一个仿函数

时间:2010-11-29 12:40:46

标签: c++ boost lambda

请查看以下简化示例:

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

错误消息(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。

为任何项目调用打印机仿函数

感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

ronag是正确的,boost的lambda引用提到“它们都将 lambda仿函数作为参数并返回void。”

似乎替代语法(bl::if_(condition)[function])不需要lambda仿函数。

但是,另一个大问题是for_each返回的函数是一个boost lambda对象,而不是你的打印机。因此,无论如何你都无法检索累积的字符串。

你可以使用这样的东西:

#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 :(得分: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。

答案 2 :(得分: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)
    ]
);