2011-09-27 67 views
25

我一直在为此搜索,而且我似乎无法找到直接的答案。有消息说这是不可能的,但这只会为我提出更多的问题,我将在下面进一步解释。传递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函数一起使用。

我想说明的是,这段代码并未按原样编译/测试。仅用于演示目的。我曾尝试在实际项目中实施相同的原则,但不起作用。

回答

12

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

+6

或者使用'的std :: function',或作出选择' '模板 – bdonlan

+0

我试过你的解决方案(在上面通过删除'&'的方式发布的确切代码),它不起作用。它给我错误C2664,因为它不能将'匿名命名空间':: '转换为'bool(__cdecl *)(const T&)'。 – Zeenobit

+1

@teedayf,它是C++ 11的一个新增功能。 Visual Studio 2010尚不支持它。你需要声明lambda为'[](const int&x){...}'来匹配函数指针签名。 – MSN

33

有没有必要添加短裤[&] -capture。你的lambda不需要它:

[] (int x) -> bool { return (x == 0); } 

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

这就是说,你应该申报select函数接受std::function,到所有 lambda表达式是敞篷车,捕捉或不:

Container<T> select(std::function<bool(const T&)> predicate) const;