make_shared
分配新的int
,並在其周圍包裝shared_ptr
。這意味着你的兩個shared_ptr<int>
指向不同的內存,並且由於你創建了一個鍵值爲指針值的散列表,它們是不同的鍵。
出於同樣的原因,這將導致一個大小爲2:
boost::unordered_set<int *> s3;
s3.insert(new int(5));
s3.insert(new int(5));
assert(s3.size() == 2);
對於您可以考慮shared_ptr
s到行爲就像指針,包括比較,除了自動銷燬的大部分。
你可以定義自己的散列函數和比較謂詞,並把它們傳遞作爲模板參數unordered_map
,雖然:
struct your_equality_predicate
: std::binary_function<boost::shared_ptr<int>, boost::shared_ptr<int>, bool>
{
bool operator()(boost::shared_ptr<int> i1, boost::shared_ptr<int> i2) const {
return *i1 == *i2;
}
};
struct your_hash_function
: std::unary_function<boost::shared_ptr<int>, std::size_t>
{
std::size_t operator()(boost::shared_ptr<int> x) const {
return *x; // BAD hash function, replace with somethign better!
}
};
boost::unordered_set<int, your_hash_function, your_equality_predicate> s4;
然而,這可能有幾個原因是一個壞主意:
- 你有令人困惑的情況,其中
x != y
但s4[x]
和s4[y]
是相同的。
如果有人通過散列鍵更改指向的值,那麼您的散列將打破!那就是:
boost::shared_ptr<int> tmp(new int(42));
s4[tmp] = 42;
*tmp = 24; // UNDEFINED BEHAVIOR
與散列函數
通常你想關鍵是不可改變的;無論以後會發生什麼,它總會比較相同。如果你使用的是指針,你通常希望指針的標識符是匹配的,如extra_info_hash[&some_object] = ...
;無論some_object
的成員是什麼,這通常都會映射到相同的散列值。在插入後鍵值不可變,實際上很容易這樣做,導致哈希中的未定義行爲。
右鍵着,當然。所以我應該能夠通過使用(智能)指針來實現相同的語義?這意味着通過以某種特定方式定義哈希函數,大小應該是1而不是2.我該怎麼做? – Jay
@Jay:更新了一個例子,並警告不要這樣做 – bdonlan