假设我有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 );
或尝试使用前迭代器的任何其他方式。
答案 0 :(得分:3)
unordered_set,顾名思义,是无序的。您可以在矢量中跟踪元素的位置,因为只要您不删除任何内容,他们就不会改变位置。但是对于unordered_set来说并非如此。例如,在我的实现中,这是在每次插入后按顺序打印所有元素的内容:
std::unordered_set<int> s;
s.insert(0); // 0
s.insert(1); // 1 0
s.insert(2); // 2 1 0
s.insert(3); // 3 2 1 0
...
s.insert(22); // 22 0 1 2 3 ... 19 20 21
...
s.insert(48); // 48 47 46 45 ... 22 0 1 2 3 4 ... 21
所以我想说的是订单肯定不是你依赖的东西。
但是,使用矢量,您可以在设置位置方面做得更好:
vector.push_back(ptr);
ptr->SetPosition(vector.size() - 1);