假设我有一个谓语:
bool my_pred(const MyType* x) {
....
}
我想过滤一些集合,因此它只包含与my_pred
不匹配的元素。理想情况下,我想写这样的东西:
using namespace std;
vector<const MyType*> elems = ...;
remove_if(begin(elems), end(elems), not(my_pred));
如何编写上面的not
高阶函数?
目标是实现以下目标(但这段代码当然不起作用):
template<typename T>
function<bool(T)> not(function<bool(T)> pred) {
return [&](T x) { return !pred(x) };
}
我尝试使用std::logical_not
,但我失败了。我希望每次想要做这样的事情时都要避免定义一个特定的lambda。
理想情况下,我想将此模式扩展到其他逻辑运算符。 也许有更好的方法来做到这一点?
谢谢!
答案 0 :(得分:2)
使用
template<typename T>
function<bool(T)> not(function<bool(T)> pred) {
return [&](T x) { return !pred(x) };
}
你通过引用捕获,但lambda生命长于捕获pred
,导致悬空指针和UB。
您应该通过复制或移动来捕获:
template<typename T>
function<bool(T)> not(function<bool(T)> pred) {
return [=](T x) { return !pred(x) };
}
你可以通过更通用来消除std::function
的开销:
template<typename F>
auto not(F pred) {
return [=](auto&& x) { return !pred(x); };
}
(要求C ++ 14)。