不推斷類型當我定義該函數,C++ 11時的std ::函數或lambda函數涉及
template<class A>
set<A> test(const set<A>& input) {
return input;
}
我可以在代碼使用test(mySet)
其他地方打電話,而不必顯式地定義模板類型。然而,當我使用下面的函數:
template<class A>
set<A> filter(const set<A>& input,function<bool(A)> compare) {
set<A> ret;
for(auto it = input.begin(); it != input.end(); it++) {
if(compare(*it)) {
ret.insert(*it);
}
}
return ret;
}
當我打電話使用此功能filter(mySet,[](int i) { return i%2==0; });
我收到以下錯誤:
error: no matching function for call to ‘filter(std::set&, main()::)’
然而,所有這些版本的做工作:
std::function<bool(int)> func = [](int i) { return i%2 ==0; };
set<int> myNewSet = filter(mySet,func);
set<int> myNewSet = filter<int>(mySet,[](int i) { return i%2==0; });
set<int> myNewSet = filter(mySet,function<bool(int)>([](int i){return i%2==0;}));
爲什麼當我將lambda函數directl時,C++ 11無法猜測模板類型y表達式內部沒有直接創建std::function
?
編輯:
每呂克丹東的意見在評論,這裏是功能我早些時候曾不需要模板被明確傳遞了一個替代方案。
template<class A,class CompareFunction>
set<A> filter(const set<A>& input,CompareFunction compare) {
set<A> ret;
for(auto it = input.begin(); it != input.end(); it++) {
if(compare(*it)) {
ret.insert(*it);
}
}
return ret;
}
無需模板即可調用set<int> result = filter(myIntSet,[](int i) { i % 2 == 0; });
。
編譯器甚至可以在某種程度上使用新的decltype關鍵字並使用新函數返回類型語法來猜測返回類型。下面是一組轉換爲地圖,使用一個濾波函數,並且基於該值生成密鑰一個函數的一個例子:
template<class Value,class CompareType,class IndexType>
auto filter(const set<Value>& input,CompareType compare,IndexType index) -> map<decltype(index(*(input.begin()))),Value> {
map<decltype(index(*(input.begin()))),Value> ret;
for(auto it = input.begin(); it != input.end(); it++) {
if(compare(*it)) {
ret[index(*it)] = *it;
}
}
return ret;
}
它也可以不直接使用模板調用,因爲
map<string,int> s = filter(myIntSet,[](int i) { return i%2==0; },[](int i) { return toString(i); });
與你的問題無關,但你確實意識到你的'filter'本質上等同於'std :: copy_if'的非通用版本,不是嗎? – 2012-04-03 17:45:07
啊,我不知道std :: copy_if,謝謝你指出。然而,這是一組更大的4個函數的一部分,其中一個在過濾時轉換set => map,而我沒有看到用copy_if實現這個函數的方法,並允許用戶使用集合中的值生成密鑰。爲了使用的一致性,我選擇這樣做。 – Datalore 2012-04-03 18:27:31
爲了記錄,如果你想接受一個仿函數,通常把它作爲一個通用的模板參數,即'template set filter(set const&input,Predicate compare);'。正如你剛剛目睹的那樣,'std :: function'不能證明傳入的謂詞應該有一個與bool(A)匹配的簽名;還有其他方法可以做到這一點。此外,在使用'std :: function'作爲函數參數時存在*其他*缺點。 –
2012-04-04 03:11:53