如何使用一些 boost 库使 std::find_if 和 std::map 一起工作?
这个问题的灵感来自 另一个问题提出这个问题的主题:
从地图容器中查找第一个大于用户指定值的值
这可以通过多种方式解决。典型的 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; }
);
即 接受的回答。
我仍在寻找一个简短而酷的解决方案。如果它是一个向量,那么我刚刚学习了一个很酷的解决方案,它利用 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 & 作为参数的函子。我的直觉告诉我 boost 有这个解决方案。 :-)
This question is inspired from another topic which poses this question:
Find the first value greater than user specified value from a map container
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.
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; }
);
which is the accepted answer.
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);
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
.
A quick test is (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
Or,
auto it = std::find_if(m.begin(),mp.end(), at<1>(arg1) > n); //m is std::map
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. :-)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实上,Boost.Fusion 和 Boost.Phoenix 正是您想要的内置内容。
如果包含必要的标头来 adapt
std::pair<>
作为符合 Fusion 序列,然后可以使用 Phoenix 的惰性版本boost::fusion::at_c
来访问std::pair<>::first
或std::pair<>::second
(请务必#include
)。编辑:完整示例,使用 VC++ 2010 SP1 + Boost 1.47.0 进行测试:
Indeed, Boost.Fusion and Boost.Phoenix have exactly what you want built-in.
If one includes the necessary header to adapt
std::pair<>
as a conforming Fusion sequence, then one can use Phoenix's lazy version ofboost::fusion::at_c<>
to accessstd::pair<>::first
orstd::pair<>::second
(be sure to#include <boost/phoenix/fusion.hpp>
).EDIT: Full sample, tested with VC++ 2010 SP1 + Boost 1.47.0: