c++ - 我怎样才能使 std::find_if 和 std::map 使用一些 boost 库协同工作?

标签 c++ boost map boost-fusion boost-phoenix

这个问题的灵感来自another topic这提出了这个问题:

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

可以通过多种方式解决。典型的 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; }
                   );

这是the accepted answer .

我仍在寻找一个简短而酷的解决方案。如果它是一个 vector ,那么我刚刚学到了一个很酷的解决方案,它利用了 Boost.Phoenix并且解决方案变得非常简洁(ideone demo):

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

在这里arg1boost::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

我的问题是,我想以类似的方式解决 map 问题。有没有这样的解决方案?像这样的东西:

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.Fusion 和 Boost.Phoenix 内建了您想要的一切。

如果将必要的 header 包含到 adapt std::pair<> as a conforming Fusion sequence , 然后可以使用 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);

编辑:完整示例,使用 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"
}

关于c++ - 我怎样才能使 std::find_if 和 std::map 使用一些 boost 库协同工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7337414/

相关文章:

java - java.util.TreeMap 的子类在调用 put(key, value) 方法时给出 NullPointerException

c++ - 多项式哈希码结果为负数?

c++ - 容器和派生类

c++ - C++中大尺寸的堆栈分配

c++ - 在 Boost.Log 中正确重载运算符 <<

javascript - Jquery Map with Single Image with drag,pan and zoom

python - Ruby 和 Javascript 中 map 的 Python 等价物是什么?

c++ - C++ Windows/Mac/iOS 中的西类牙字符

c++ - 用 C++ 进行 CSV 解析/编写的首选库是什么?

c++ - boost io_service 非阻塞并行执行?