我怎样才能让的std :: find_if和std ::地图共同努力使用一些Boost库? [英] How can I make std::find_if and std::map work together using some boost library?

查看:325
本文介绍了我怎样才能让的std :: find_if和std ::地图共同努力使用一些Boost库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是来自<一个灵感href=\"http://stackoverflow.com/questions/7335546/find-the-first-value-greater-than-user-specified-value-from-a-map-container\">another话题这对这样一个问题:

This question is inspired from another topic which poses this question:

查找地图容器中第一个值大于用户指定的值时

Find the first value greater than user specified value from a map container

这可以通过多种方式来解决。一个典型的C ++ 03的解决方案定义了一个专门的函数(或仿函数),并把它传递给的std :: find_if 作为第三个参数。

which can be solved in several ways. A typical C++03 solution defines a dedicated function (or functor) and pass it to std::find_if as third argument.

在C ++ 11,他就会避免定义的专用的函数(或仿函数),而是可以使用的λ为:

In C++11, one can avoid defining a dedicated function (or functor), and can instead make use of lambda as:

auto it = std:: find_if(m.begin(), mp.end(), 
                    [n](const std::pair<std::string, int> & x) -> bool
                       { return x.second > n; }
                   );

这是<一个href=\"http://stackoverflow.com/questions/7335546/find-the-first-value-greater-than-user-specified-value-from-a-map-container/7335623#7335623\">the接受的答案。

我还在寻找一个短暂而凉爽的解决方案。如果它是一个矢量,然后我就学会了一个很酷的解决方案,它利用 Boost.Phoenix 和解决方案变得非常简洁(的 ideone演示):

I'm still looking for a short and cool solution. If it were a vector, then I just learnt a cool solution which makes use of Boost.Phoenix and the solution becomes very concise (ideone demo):

std::vector<int> v = ...;
auto it = std::find_if(v.begin(), v.end(), arg1 > 4);

下面 ARG1 是的boost ::凤凰:: arg_names 命名空间定义一个仿函数对象,和前pression ARG1方式&gt; 4 计算为另一个仿函数然后把它传递给的std :: find_if

Here arg1 is a functor object defined in boost::phoenix::arg_names namespace, and the expression arg1>4 evaluates to another functor which then gets passed to std::find_if.

一个快速测试( ideone

std::cout<< (arg1 > 9)(v) << std::endl; //prints 0 if as v > 9 is false, else 1

//or store the functor first and then use it
const auto & f = arg1 > 9;
std::cout<<  f(v) << std::endl; //prints 0 if as v > 9 is false, else 1


我的问题是,我想解决这个问题的地图,以类似的方式。有没有这样的解决方案?是这样的:


My question is, I want to solve the map problem, in a similar way. Is there any such solution? Something like:

auto it = std::find_if(m.begin(),mp.end(), (???).second > n); //m is std::map

或者

auto it = std::find_if(m.begin(),mp.end(), at<1>(arg1) > n);  //m is std::map

有关它的工作,前pression AT&LT; 1 GT;(ARG1)GT; 2 必须评估一个仿函数这需要常量的std ::对&安培; 作为参数。我的直觉告诉我,提振了该解决方案。 : - )

For it to work, the expression at<1>(arg1) > 2 has to evaluate to a functor which takes const std::pair & as argument. My gut feelings tells me that boost has this solution. :-)

推荐答案

事实上,Boost.Fusion和Boost.Phoenix有你想要内置的是什么。

Indeed, Boost.Fusion and Boost.Phoenix have exactly what you want built-in.

如果一个包括必要的头适应 STD ::对&LT;&GT; 为符合融合序列,那么可以使用Phoenix的的懒惰版本的boost ::融合:: at_c&LT;&GT; 访问的std ::对&LT;&GT; ::第一个的std ::对&LT;&GT; ::第二个(一定要的#include&LT;升压/凤凰/ fusion.hpp&GT; )。

If one includes the necessary header to adapt std::pair<> as a conforming Fusion sequence, then one can use Phoenix's lazy version of boost::fusion::at_c<> to access std::pair<>::first or std::pair<>::second (be sure to #include <boost/phoenix/fusion.hpp>).

namespace phx = boost::phoenix;
using phx::arg_names::arg1;

auto it = std::find_if(m.begin(), m.end(), phx::at_c<1>(arg1) > n);


编辑:展开样品,用VC ++ 2010 SP1 +升压1.47.0测试:


Full sample, tested with VC++ 2010 SP1 + Boost 1.47.0:

#include <algorithm>
#include <map>
#include <string>
#include <iostream>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/phoenix/fusion.hpp>

int main()
{
    namespace phx = boost::phoenix;
    using phx::arg_names::arg1;

    std::map<std::string, int> m;
    m["foo"]    = 1;
    m["bar"]    = 2;
    m["baz"]    = 3;
    m["qux"]    = 4;
    m["quux"]   = 5;
    m["corge"]  = 6;
    m["grault"] = 7;
    m["garply"] = 8;
    m["waldo"]  = 9;
    m["fred"]   = 10;
    m["plugh"]  = 11;
    m["xyzzy"]  = 12;
    m["thud"]   = 13;

    int const n = 6;
    auto it = std::find_if(m.cbegin(), m.cend(), phx::at_c<1>(arg1) > n);
    if (it != m.cend())
        std::cout << it->first << '\n'; // prints "fred"
}

这篇关于我怎样才能让的std :: find_if和std ::地图共同努力使用一些Boost库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆