Naw*_*waz 6 c++ boost map boost-fusion boost-phoenix
从地图容器中查找大于用户指定值的第一个值
这可以通过几种方式解决.典型的C++ 03解决方案定义了一个专用函数(或仿函数)并将其std::find_if
作为第三个参数传递给它.
在C++ 11中,可以避免定义专用函数(或函子),而是可以使用lambda
as:
auto it = std:: find_if(m.begin(), mp.end(),
[n](const std::pair<std::string, int> & x) -> bool
{ return x.second > n; }
);
Run Code Online (Sandbox Code Playgroud)
这是公认的答案.
我还在寻找一个简短而酷的解决方案.如果它是一个矢量,那么我刚刚学会了一个很酷的解决方案,它使用Boost.Phoenix
了解决方案变得非常简洁(ideone demo):
std::vector<int> v = ...;
auto it = std::find_if(v.begin(), v.end(), arg1 > 4);
Run Code Online (Sandbox Code Playgroud)
这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
Run Code Online (Sandbox Code Playgroud)
我的问题是,我想以类似的方式解决地图问题.有没有这样的解决方案?就像是:
auto it = std::find_if(m.begin(),mp.end(), (???).second > n); //m is std::map
Run Code Online (Sandbox Code Playgroud)
要么,
auto it = std::find_if(m.begin(),mp.end(), at<1>(arg1) > n); //m is std::map
Run Code Online (Sandbox Code Playgroud)
为了使它工作,表达式at<1>(arg1) > 2
必须评估为一个以const std::pair &
参数为参数的仿函数.我的直觉告诉我,提升有这个解决方案.:-)
实际上,Boost.Fusion和Boost.Phoenix正是你想要的内置.
如果一个包含必要的标题以适应std::pair<>
符合的Fusion序列,那么可以使用Phoenix的懒惰版本boost::fusion::at_c<>
来访问std::pair<>::first
或std::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);
Run Code Online (Sandbox Code Playgroud)
编辑:完整示例,使用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"
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2725 次 |
最近记录: |