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

标签 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;

为了计算 vector 中的位置,我的对象指针被放置了。

但是,如果我想使用 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. 有没有什么方法可以使用类似于上述代码的方式安全地获取插入指针的位置?

最佳答案

unordered_set,顾名思义,是无序的。您可以跟踪元素在 vector 中的位置,因为只要您不删除任何内容,它们就不会改变位置。但 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 ,您可以在设置位置方面做得更好:

vector.push_back(ptr);
ptr->SetPosition(vector.size() - 1);    

关于c++ - std::unordered_set insert,获取插入项的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26413490/

相关文章:

c++ - 模板函数参数类型中的模板标识符与 decltype

c++ - 使用 find 在 unordered_set 中查找多个值

c++ - 什么是更快的阅读,ASCII 或二进制?

c++ - 如何为一个虚函数提供多个覆盖

c++ - 将声明为 INT/UINT 的八进制/十六进制分配给另一个变量

windows - 使用 std::bind 的代码无法编译,错误 C2780:需要 6 个参数 - 提供了 8 个参数

c++ - 数组因第一个索引而崩溃

c++ - 为什么 std::reference_wrapper<const T> 不接受临时的?

c++ - 将元素存储在 unordered_set 中与将它们存储在 unordered_map 中

c++ - 如何在迭代时有效地替换 unordered_set 中的元素?