帮助我使用调用函子的 boost::lambda::if_then 表达式

发布于 2024-10-04 13:22:27 字数 2519 浏览 2 评论 0原文

请看一下下面的简化示例:

#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 函子。

感谢您的帮助!

Please have a look at the following simplified example:

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

Any hints what's wrong with that code?

It is supposed to call the Printer functor for any item with item.soll == item.ist.

Thanks for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

旧城空念 2024-10-11 13:22:27

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 实际上没有做任何有用的事情,所以除了一些琐碎的事情之外,我不会不遗余力地使用它。

ronag is correct, boost's lambda reference mentions that "They all take lambda functors as parameters and return void."

It seems that the alternative syntax (bl::if_(condition)[function]) does not require lambda functors.

However, another big problem is that for_each returns the functor which is a boost lambda object, not your Printer. Therefore you'll have no way to retrieve the accumulated string anyway.

You might get it to work with something like this:

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

However,

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

}

would be a lot simpler to get what you want. for_each does virtually nothing useful, so I wouldn't go out of my way to use it for nothing but trivial things.

哆兒滾 2024-10-11 13:22:27

试试这个:

 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。

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

It seems to me that bl::if_then does not accept any functor, it needs to be a lambda_functor.

一口甜 2024-10-11 13:22:27

正确答案已经提供。只是提供一个不涉及 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)
    ]
);

Correct answers have already been provided. Just offering an alternative which doesn't involve a Printer object :

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)
    ]
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文