std :: unordered_set insert,获取插入项的位置

时间:2014-10-16 20:38:18

标签: c++ c++11 unordered-set

假设我有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 );

或尝试使用前迭代器的任何其他方式。

  1. 这有意义吗?或者我应该依赖set.size()和假设我的指针插在最后?
  2. 有没有办法使用类似于上面代码的东西安全地获取插入指针的位置?

1 个答案:

答案 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);