首先,正如Richard Hodges在他的回答中所說的那樣,您不能使用std::weak_ptr
作爲關鍵字,因爲它不穩定。忽略這一點,我們可以看一下一般問題:我們可以使用lambdas作爲模板參數嗎?
通用解決方案是按照the following answer中所述進行操作。有兩件事要注意
- lambda必須單獨定義。
- lambda必須作爲參數傳入。
2)的原因是從編譯器爲lambda創建的類型中刪除了默認構造函數。
對於std::set
這並不壞,但考慮到其std::unordered_map
沒有構造函數取一個鍵比較功能:
auto compare = [](const A & lhs, const A & rhs) { return lhs==rhs; };
std::unordered_map<
A,
B,
std::hash<A>,
decltype(compare)
> map1{0, std::hash<A>{}, compare};
第一個參數是初始桶大小,並且是實現定義。我正在使用0,假設實現將在插入第一個項目時找到優化值。第二個是散列函數,最後是lambda。
我們可以通過用function<bool(A,A)>
代替decltype(...)
來改善它。這允許我們在頭中聲明類型,並將其傳遞給其他函數,而不需要共享實際的lambda。該宣言將成爲:
typedef std::unordered_map<
A,
B,
std::hash<A>,
std::function<bool(A,A)>
> custom_unordered_map;
而且它可以如下使用:
custom_unordered_map map2{0, std::hash<A>{},
[](const A & lhs, const A & rhs) { return lhs==rhs; } };
該解決方案將允許自定義的lambda表達式直接,也使用免費的功能。
該解決方案的主要優點是它允許使用不同的比較函數,但它使用起來非常冗長。
如果只需要一個單一的比較功能,一個更簡潔的解決方案(針對類型的用戶)是定義一個算符:
struct Compare {
bool operator() (const A & lhs, const A & rhs) {
return lhs==rhs;
}
};
這然後可以在正常的方式使用:
std::unordered_map<A, B, std::hash<A>, Compare> map4;
注:使用此解決方案可以使用默認構造函數。
下面是一個完整的例子:
#include <functional>
#include <memory>
#include <unordered_map>
using A = int;
using B = int;
struct Compare {
bool operator() (const A & lhs, const A & rhs) {
return lhs==rhs;
}
};
bool compare_func(const A & lhs, const A & rhs) {
return lhs==rhs;
}
int main() {
// Using lamda: default constructor is deleted, so the lambda
// must be passed as argument to the constructor.
auto compare = [](const A & lhs, const A & rhs) { return lhs==rhs; };
std::unordered_map<
A,
B,
std::hash<A>,
decltype(compare)
> map1{0, std::hash<A>{}, compare};
// Alternative: use std::function. More general, and allows any lambda to be used
typedef std::unordered_map<
A,
B,
std::hash<A>,
std::function<bool(A,A)>
> custom_unordered_map;
custom_unordered_map map2{0, std::hash<A>{},
[](const A & lhs, const A & rhs) { return lhs==rhs; } };
custom_unordered_map map3{0, std::hash<A>{}, compare_func};
// Use of function class
std::unordered_map<A, B, std::hash<A>, Compare> map4;
}
這可以在Ubuntu 15.10使用命令g++ map_lambda.cpp --std=c++11 -o map_lambda
進行編譯。
我的個人意見是使用最後的解決方案,除非需要使用不同的函數進行密鑰比較。
試試'decltype([](...){...})'。 – kukyakya
@kukyakya這不是合法的C++,即使它編譯。 – Yakk