提升 lambda 集合大小评估
Posted
技术标签:
【中文标题】提升 lambda 集合大小评估【英文标题】:boost lambda collection size evaluation 【发布时间】:2009-03-23 06:45:10 【问题描述】:我有一个函数的形式:
void DoSomething(const boost::function<bool ()>& condition, other stuff);
这个函数做一些工作并且只在条件为真时返回。该条件已表示为函子参数,因为我想在不同的调用站点提供不同的条件。
现在,直接使用它相当简单,但它需要声明许多小的一次性函数或仿函数对象,如果可能的话,我想避免这些。我一直在研究 Boost 的 lambda 库,以寻找消除这些问题的可能方法,但我认为我缺少一些基本的东西;我就是不能让它做我想做的事。
目前让我感到难过的一个案例:我有一个名为 data
的 std::vector
集合;我所追求的条件是当该集合的size()
达到某个阈值时。那么,本质上,我希望我的condition
函子在data.size() >= threshold
时返回true,否则返回false。但我在用 lambda 语法表达时遇到了麻烦。
到目前为止,我能想到的最好的(至少可以编译,尽管它不起作用)是这样的:
boost::function<bool (size_t)> ge = boost::bind(std::greater_equal<size_t>(),
_1, threshold);
boost::function<size_t ()> size = boost::bind(&std::vector<std::string>::size,
data);
DoSomething(boost::lambda::bind(ge, boost::lambda::bind(size)), other stuff);
在进入 DoSomething
时,大小为 0——即使在运行过程中大小增加,对 condition()
的调用似乎总是大小为 0。跟踪它(这是Boost 的内部结构有点棘手),虽然每次评估 condition()
时它似乎都在调用 greater_equal
,但它似乎并没有调用 size()
。
那么,我完全搞砸了什么基本的事情?有没有更简单的方式来表达这种事情(同时仍然尽可能保持代码内联)?
理想情况下,我希望它尽可能接近 C# 等效代码流畅度:
DoSomething(delegate() return data.size() >= threshold; , other stuff);
DoSomething(() => (data.size() >= threshold), other stuff);
【问题讨论】:
【参考方案1】:问题在于,lambda 函数存储了data
向量的副本,而不是引用。所以 size()
是在副本上调用的,而不是你正在修改的原始对象。这可以通过用boost::ref
包装data
来解决,它存储一个引用:
boost::function<size_t ()> size = boost::bind(&std::vector<std::string>::size,
boost::ref(data));
您还可以在 lambda 函数的定义中使用普通的 >=
运算符而不是 std::greater_equal<>
并将它们组合在一起:
boost::function<bool ()> cond =
(boost::bind(&std::vector<std::string>::size, boost::ref(data))
>= threshold);
DoSomething(cond, other stuff);
【讨论】:
谢谢,成功了。虽然令我感到惊讶的是,您可以像这样将 >= 应用于绑定函数——尤其是因为它甚至不是 lambda 绑定! :) 函数对象的 >= 被重载,但也许 boost::lambda::bind 无论如何都是更好的选择...以上是关于提升 lambda 集合大小评估的主要内容,如果未能解决你的问题,请参考以下文章