【发布时间】:2014-10-16 20:38:17
【问题描述】:
假设我有类 MyClass
class MyClass
{
public:
MyClass( std::string str ) : _str(str) {}
void SetPosition ( int i ) { _pos = i; }
std::string _str;
int _pos;
};
namespace std
{
template<> struct hash<shared_ptr<MyClass>>
{
size_t operator()( const shared_ptr<MyClass> & ptr ) const
{
return hash<string>()( ptr->_str ) + hash<int>()( ptr->_pos );
}
};
}
当使用 std::vector 时,我能够做到这一点:
std::string str = "blah";
auto ptr = std::make_shared<MyClass>( str );
std::vector<std::shared_ptr<MyClass>> vector;
vector.push_back( ptr );
ptr->SetPosition ( std::addressof( vector.back() ) - std::addressof( vector[0] ) );
std::cout << ptr->_str << " is at " << ptr->_pos << std::endl;
为了计算向量中的位置,我的对象指针被放置了。
但是,如果我想使用 std::unordered_set(我这样做),那么:
std::string str = "blah";
auto ptr = std::make_shared<MyClass>( str );
std::unordered_set<std::shared_ptr<MyClass>> set;
auto res = set.insert( ptr );
ptr->SetPosition ( std::addressof( res.first ) - std::addressof( set[0] ) );
std::cout << ptr->_str << " is at " << ptr->_pos << std::endl;
不会工作。 也不会
std::addressof( set.begin() );
也不会,
std::addressof( set.begin().first );
或我尝试使用前端迭代器的任何其他方式。
- 这有意义吗?或者我应该依赖 set.size() 并 假设 我的指针被插入到最后?
- 是否有任何方法可以使用与上述代码类似的方法安全地获取插入该指针的位置?
【问题讨论】:
-
位置对于无序集没有多大意义,因为它是无序的。
-
不仅是无序的,您的项目在集合中的位置可能会在插入后发生变化。例如,哈希可能会切换哈希函数并复制到更大的结构中。
-
当然,将来插入无序集合的数据可能会在您的项目之前进入哈希桶,从而将其推到更远的位置。
标签: c++ c++11 unordered-set