我如何使std::find_if和std::map使用一些boost库一起工作

How can I make std::find_if and std::map work together using some boost library?

本文关键字:std boost 一起 工作 何使 find if map      更新时间:2023-10-16

这个问题的灵感来自于另一个话题,这个话题提出了这个问题:

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

可以用几种方法解决。典型的c++ 03解决方案定义了一个专用函数(或函子),并将其作为第三个参数传递给std::find_if

在c++ 11中,可以避免定义专用的函数(或函子),而可以使用lambda作为:
auto it = std:: find_if(m.begin(), mp.end(), 
                    [n](const std::pair<std::string, int> & x) -> bool
                       { return x.second > n; }
                   );

是被接受的答案。

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

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

这里arg1是在boost::phoenix::arg_names命名空间中定义的函子对象,表达式arg1>4求值为另一个函子,然后传递给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

我的问题是,我想用类似的方法解决地图问题。有这样的解决办法吗?比如:

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

要使其工作,表达式at<1>(arg1) > 2必须求值为以const std::pair &为实参的函子。我的直觉告诉我boost有这个解决方案。: -)

确实,Boost。聚变和增强。凤凰有你想要的内置。

如果一个人包含了必要的头来适应std::pair<>作为一个符合Fusion序列,那么一个人可以使用Phoenix的延迟版本boost::fusion::at_c<>来访问std::pair<>::firststd::pair<>::second(一定要访问#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);

EDIT:完整示例,测试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"
}