2011-09-07 66 views
6

这个问题是来自another topic灵感这对这样一个问题:我怎样才能使std :: find_if和std :: map一起使用一些boost库?

找到的第一个值不是用户指定的值从地图容器

这可以通过多种方式来解决更大。一个典型的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

我仍在寻找一个简短而酷的解决方案。如果它是一个向量,那么我刚学会阴凉溶液这使得Boost.Phoenix使用,并将该溶液变得非常简明(ideone demo):

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 &作为参数。我的直觉感受告诉我,提升有这个解决方案。 :-)

+0

你只想要查找的值(在这种情况下的http:// www.boost.org/doc/libs/release/libs/range/doc/html/range/reference/adaptors/reference/map_values.html是答案),或者是整个关键字,值对的迭代器,其中值满足谓词? – Cubbi

+0

@Cubbi:如果这不适用于返回地图的迭代器的'std :: find_if',那不是答案。 – Nawaz

+0

@Nawaz:我不知道是否需要std :: find_if。如果没有,我会去http://www.cplusplus.com/reference/stl/map/upper_bound/这应该是更快,只有一个简单的代码行。 –

回答

9

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

如果一个包括必要的头adapt std::pair<> as a conforming Fusion sequence,那么可以用凤凰的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 +升压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" 
} 
+0

请发布一个完整的工作和测试的解决方案。我不想说它不会编译或不工作。虽然,我正在努力做你的建议。 – Nawaz

+0

@Nawaz:编辑。 – ildjarn

+0

好的。我试着编译它,编译失败:http://ideone.com/EgALC – Nawaz

相关问题