2011-09-27 66 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;