传递 C++ Lambda 函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7573857/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing C++ Lambda Functions
提问by Zeenobit
I've been searching everywhere for this, and I don't seem to be able to find a straight answer. Some sources say this isn't possible, but that only raises more questions for me, which I'll explain further below.
我一直在到处寻找这个问题,但似乎无法找到直接的答案。一些消息来源说这是不可能的,但这只会给我带来更多问题,我将在下面进一步解释。
So here's the situation. Suppose I have a custom container class with a selection function like below (this is just an example):
所以这里的情况。假设我有一个带有如下选择功能的自定义容器类(这只是一个示例):
template <typename T>
class Container {
public:
// ...
Container<T> select(bool (*condition)(const T&)) const;
// ...
};
So as you can see, the select
function takes a pointer to a conditionfunction. This is a function that defines which items should be selected. So, an example use of this would be something similar to:
如您所见,该select
函数接受一个指向条件函数的指针。这是一个定义应选择哪些项目的函数。因此,它的示例用法类似于:
bool zero_selector(const int& element) {
return (element == 0); // Selects all elements that are zero
}
Now if I have a container filled with, say s = { 1, 1, 0, 0, 1, 0, 1, 0 }
, I could select a subset of these that would only contain zeroes using:
现在,如果我有一个装满的容器,例如s = { 1, 1, 0, 0, 1, 0, 1, 0 }
,我可以使用以下方法选择其中只包含零的一个子集:
t = s.select(&zero_selector); // t = { 0, 0, 0, 0 }
As you can see, this is a bit clunky. Lambda functions would make this much more elegant, so then I could use (I'm not sure if this is the correct syntax for it), for example:
如您所见,这有点笨拙。Lambda 函数会使这更加优雅,所以我可以使用(我不确定这是否是正确的语法),例如:
t = s.select([&] (int x) -> bool { return (x == 0); });
My question is, is this possible? If so, what should my function prototype be for Container::select()
to accept a lambda as one of its parameters?
我的问题是,这可能吗?如果是这样,我的函数原型应该是什么Container::select()
来接受 lambda 作为其参数之一?
If it isn't possible, then how is something like std::for_each
implemented that can use a lambda expression as one of its arguments? Any resources that would clearly explain this would be much appreciated. Everything I've found just gives examples of lambda functions and using std::function<>
to pass them as parameters, but nothing explains how std::for_each
works with lambda functions.
如果不可能,那么如何std::for_each
实现可以使用 lambda 表达式作为其参数之一的东西?任何能清楚解释这一点的资源将不胜感激。我发现的一切只是给出了 lambda 函数的例子,并使用std::function<>
它们作为参数传递,但没有解释std::for_each
lambda 函数是如何工作的。
I'd like to note that this code isn't compiled/tested as-is. It's for demonstration purposes only. I have tried implementing the same principles in the actual project and it doesn't work.
我想指出,此代码未按原样编译/测试。它仅用于演示目的。我曾尝试在实际项目中实施相同的原则,但没有奏效。
采纳答案by MSN
You need to declare your lambda as stateless (that is, with an empty capture specification [](int x)-> bool {...}
) for it to be convertable to a function pointer.
您需要将 lambda 声明为无状态(即,具有空的捕获规范[](int x)-> bool {...}
)才能将其转换为函数指针。
回答by Kerrek SB
There's no need to add the knee-jerk [&]
-capture. Your lambda doesn't need it:
没有必要添加下意识的[&]
捕捉。你的 lambda 不需要它:
[] (int x) -> bool { return (x == 0); }
Captureless lambdas are convertible to the corresponding function pointer, so this should work out of the box.
Captureless lambdas 可以转换为相应的函数指针,所以这应该是开箱即用的。
That said, you should probably declare the select function to accept std::function
, to which alllambdas are convertible, capturing or not:
也就是说,您可能应该将 select 函数声明为 accept std::function
,所有lambdas 都可以转换,捕获或不捕获:
Container<T> select(std::function<bool(const T&)> predicate) const;