传递C ++ Lambda函数

时间:2011-09-27 18:20:34

标签: c++ lambda

我一直在寻找这个,我似乎无法找到一个直接的答案。一些消息来源说这是不可能的,但这只会给我带来更多问题,我将在下面进一步解释。

所以这就是情况。假设我有一个带有如下选择函数的自定义容器类(这只是一个例子):

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函数。

我想请注意,此代码未按原样编译/测试。它仅用于演示目的。我尝试在实际项目中实现相同的原则,但它不起作用。

2 个答案:

答案 0 :(得分:39)

无需添加膝跳[{1}} - 捕捉。你的lambda不需要它:

[&]

无捕捉的lambdas可以转换为相应的函数指针,所以这应该是开箱即用的。

那就是说,你应该声明select函数接受[] (int x) -> bool { return (x == 0); } 所有 lambdas都可以转换,捕获与否:

std::function

答案 1 :(得分:17)

您需要将lambda声明为无状态(即使用空捕获规范[](int x)-> bool {...}),以便将其转换为函数指针。