C 11 中的std::function 和Lambda 函數的類型推導
在C 11 中使用模板時,類型推導可以是模板時,類型推導可以是強大的功能。但是,在某些情況下,類型推導會失敗,特別是當涉及 std::function 或 lambda 函數時。
在下面的範例中,函數測試接受一組類型A 並傳回相同的集合,而無需明確指定範本類型:
template<class A> set<A> test(const set<A>& input) { return input; }
在程式碼中的其他位置使用test (mySet) 呼叫此函數可以如預期般運作。但是,當使用帶有lambda 函數的函數時,類型推導失敗:
template<class A> set<A> filter(const set<A>& input,function<bool(A)> compare) { // ... implementation }
嘗試使用filter(mySet,[](int i) { return i%2==0; }) 呼叫過濾器;導致錯誤:
error: no matching function for call to ‘filter(std::set&, main()::)’
出現此問題是因為lambda 不是函數或std::function 物件。它們是具有標準定義的特定屬性的函數物件。類型推導僅適用於精確類型,而 lambda 則不符合此條件。
要解決此問題,您可以將 lambda 轉換為 std::function 或明確提供模板類型:
// Convert lambda to std::function std::function<bool(int)> func = [](int i) { return i%2 ==0; }; set<int> myNewSet = filter(mySet,func); // Provide template type explicitly set<int> myNewSet = filter<int>(mySet,[](int i) { return i%2==0; });
或者,您可以重新定義函數以接受 CompareFunction的範本參數:
template<class A,class CompareFunction> set<A> filter(const set<A>& input,CompareFunction compare) { // ... implementation }
使用此修改後,您可以在不指定範本類型的情況下呼叫函數:
set<int> result = filter(myIntSet,[](int i) { i % 2 == 0; });
型別推導對於多參數lambda 也可能會出現問題。在這種情況下,使用 auto 可能是有用的解決方案:
template<class Value,class CompareType,class IndexType> auto filter(const set<Value>& input,CompareType compare,IndexType index) -> map<decltype(index(*(input.begin()))),Value> { // ... implementation }
可以如下呼叫此函數:
map<string,int> s = filter(myIntSet,[](int i) { return i%2==0; },[](int i) { return toString(i); });
以上是為什麼 C 11 中的 std::function 和 Lambda 函式類型推導失敗?的詳細內容。更多資訊請關注PHP中文網其他相關文章!