简体   繁体   English

使用boost实现C ++ 11 lambda

[英]Implement C++11 lambda using boost

I have a problem trying to convert my C++11 code snippet to boost. 我在尝试将C ++ 11代码片段转换为Boost时遇到问题。

Let's suppose I have a simple class: 假设我有一个简单的类:

class C
{

public:

    typedef std::vector<std::string> Info;

public:

    explicit C(Info const& info)
        : info_(info)
    {}

    std::string text(Info::size_type i) const
    {
        return info_[i];
    }

private:

    Info info_;

};

Now if I have a vector of C classes I would like to get the maximum width of a specific C::Info element using std::max_element algorithm. 现在,如果我有一个C类向量,我想使用std :: max_element算法获得特定C :: Info元素的最大宽度。

With C++11 lambdas I could do it the following way: 使用C ++ 11 lambda,我可以通过以下方式做到这一点:

C::Info::size_type const Info_0 = 0;
C::Info::size_type const Info_1 = 1;
C::Info::size_type const Info_2 = 2;

int get_max_width(std::vector<C> const& c_vec, C::Info::size_type info_n)
{
    std::vector<C>::const_iterator max = std::max_element(c_vec.cbegin(), c_vec.cend(),
        [info_n](C const& lhs, C const& rhs)
        { return lhs.text(info_n).length() < rhs.text(info_n).length(); });

    return max != c_vec.end() ? max->text(info_n).length() : 0;
}

But the problem is that I can't use C++11, so I have to go with boost. 但是问题是我不能使用C ++ 11,因此必须继续使用boost。

At the moment, the code I was able to come up with looks as follows: 目前,我能想到的代码如下:

int get_max_width(std::vector<C> const& c_vec, C::Info::size_type info_n)
{
    std::vector<C>::const_iterator max = std::max_element(c_vec.cbegin(), c_vec.cend(),
        boost::lambda::bind(&C::text, boost::lambda::_1, boost::lambda::var(info_n)) <
        boost::lambda::bind(&C::text, boost::lambda::_2, boost::lambda::var(info_n)));

    return max != c_vec.end() ? max->text(info_n).length() : 0;
}

Though it's clearly not what I want. 虽然显然不是我想要的。 The comparison is performed on the std::string objects, and I'm stuck trying to figure out how to call that length() function... 比较是在std :: string对象上执行的,我被困在试图弄清楚如何调用length()函数...

Your help is quite appreciated. 非常感谢您的帮助。

Here's a C++03 solution that uses Boost.Phoenix 这是一个使用Boost.Phoenix的C ++ 03解决方案

#include <functional>
#include <boost/phoenix.hpp>

int get_max_width(std::vector<C> const& c_vec, C::Info::size_type info_n)
{
    namespace phx = boost::phoenix;
    using namespace phx::arg_names;

    std::vector<C>::const_iterator max = std::max_element(c_vec.begin(), c_vec.end(),
        phx::bind(std::mem_fun_ref(&std::string::length), phx::bind(&C::text, arg1, phx::val(info_n))) < 
        phx::bind(std::mem_fun_ref(&std::string::length), phx::bind(&C::text, arg2, phx::val(info_n)))
      );

    return max != c_vec.end() ? max->text(info_n).length() : 0;
}

I haven't done too much testing with it, but it seems to work here . 我没有对其进行过多的测试,但是它似乎在这里起作用。

Not necessarily the answer you are asking for, but for a non c++11 approach it is useful to know that lambda expressions are similar to structs with a function operator. 不一定是您要的答案,但对于非c ++ 11的方法,了解lambda表达式类似于具有函数运算符的结构很有用。

So your example could be implemented something like this: 因此,您的示例可以这样实现:

struct lambda_max
{
    const C::Info::size_type& info_n;

    lambda_max(const C::Info::size_type& info_n):info_n(info_n) {}

    bool operator()(C const& lhs, C const& rhs) const
    {
        return lhs.text(info_n).length() < rhs.text(info_n).length();
    }
};

int get_max_width(std::vector<C> const& c_vec, C::Info::size_type info_n)
{
    std::vector<C>::const_iterator max = std::max_element(c_vec.cbegin(), c_vec.cend(),
        lambda_max(info_n));

    return max != c_vec.end() ? max->text(info_n).length() : 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM