我一直在寻找这个,我似乎无法找到一个直接的答案。一些消息来源说这是不可能的,但这只会给我带来更多问题,我将在下面进一步解释。
所以这就是情况。假设我有一个带有如下选择函数的自定义容器类(这只是一个例子):
template <typename T>
class Container {
public:
// ...
Container<T> select(bool (*condition)(const T&)) const;
// ...
};
如您所见,select
函数指向条件函数。这是一个定义应选择哪些项目的函数。因此,使用此示例将类似于:
bool zero_selector(const int& element) {
return (element == 0); // Selects all elements that are zero
}
现在,如果我有一个容器填充,比如s = { 1, 1, 0, 0, 1, 0, 1, 0 }
,我可以选择这些只包含零的子集:
t = s.select(&zero_selector); // t = { 0, 0, 0, 0 }
正如你所看到的,这有点笨拙。 Lambda函数会使这更加优雅,所以我可以使用(我不确定这是否是正确的语法),例如:
t = s.select([&] (int x) -> bool { return (x == 0); });
我的问题是,这可能吗?如果是这样,我的函数原型应该是什么Container::select()
接受lambda作为其参数之一?
如果不可能,那么如何实现像std::for_each
那样可以使用lambda表达式作为其参数之一?任何可以清楚解释这一点的资源都会非常感激。我发现的所有内容都给出了lambda函数的示例,并使用std::function<>
将它们作为参数传递,但没有解释std::for_each
如何使用lambda函数。
我想请注意,此代码未按原样编译/测试。它仅用于演示目的。我尝试在实际项目中实现相同的原则,但它不起作用。
答案 0 :(得分:39)
无需添加膝跳[{1}} - 捕捉。你的lambda不需要它:
[&]
无捕捉的lambdas可以转换为相应的函数指针,所以这应该是开箱即用的。
那就是说,你应该声明select函数接受[] (int x) -> bool { return (x == 0); }
,所有 lambdas都可以转换,捕获与否:
std::function
答案 1 :(得分:17)
您需要将lambda声明为无状态(即使用空捕获规范[](int x)-> bool {...}
),以便将其转换为函数指针。