make_shared
分配一个新的int
,并shared_ptr
环绕它。这意味着您的两个shared_ptr<int>
s 指向不同的 memory,并且由于您正在创建一个以指针值为键的哈希表,因此它们是不同的键。
出于同样的原因,这将导致大小为 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
' 的成员可能是什么。由于插入后键是可变的,实际上这样做太容易了,从而导致散列中的未定义行为。