【问题标题】:Multi-index on boost::ptr_vectorboost::ptr_vector 上的多索引
【发布时间】:2014-10-21 21:08:30
【问题描述】:

我在一个程序中有以下课程。

class Class1 {

    public:

        boost::ptr_vector<Class2> fields;
}

class Class2 {

    public:

        std:string name;
        unsigned int value;
}

我想在Class1 中编写一个成员函数,它基于 Class2 的 name 变量返回指向 fields 中元素的引用或指针。我不必关心容器中对象的生命周期。

目前,在函数从向量的开头搜索到元素后,我将迭代器返回到我想要的元素。

boost::ptr_vector<Class2>::iterator getFieldByName(std::string name) {

    boost::ptr_vector<Class2>::iterator field = fields.begin();

    while (field != fields.end()) {

        if (field->name.compare(name) == 0) {
            return field;
        }
        ++field;
    }

    return fields.end();
}

我面临的问题是:

(1.) 我需要快速随机访问元素,否则程序在getFieldByName() 中的停留时间过长(boost::ptr_vector&lt;&gt; 在容器开头启动时太慢了)

(2.) 我需要保留字段的插入顺序(所以我不能直接使用boost::ptr_map&lt;&gt;

我发现了 Boost::MultiIndex,它似乎可以解决问题,但我需要使用智能容器,这样容器的销毁也会破坏容器拥有的对象。

有没有办法实现具有多种访问方法的智能容器?

【问题讨论】:

  • 取消引用迭代器。它返回的值是一个引用。返回它,也作为参考。
  • @Brent 我肯定会在我的最后一个函数中这样做。我更关心的是快速访问数据并保留插入顺序
  • 哦,我明白了。你想要 O(log(n)) 查找而不是 O(n)。巴里的回答似乎还不错。
  • 假设 ptr_vector 中的插入位于末尾,您可以使用 map 对其进行索引,将名称与偏移量配对(push_back() 之前的大小)。在地图中查找名称并使用配对的偏移量来索引向量。删除有点麻烦,因为您必须在删除点之后重新索引元素。

标签: c++ algorithm boost containers


【解决方案1】:

您可以使用两个容器。有一个存储实际数据的boost::ptr_map&lt;&gt;,然后有一个存储指向地图节点的指针的std::vector&lt;&gt;

boost::ptr_map<std::string, Class2> by_field;
std::vector<Class2 const*> by_order;

void insert(Class2* obj) {
    if (by_field.insert(obj->name, obj).second) {
        // on insertion success, also add to by_order
        by_order.push_back(obj);
    }
}

这将让您在getFieldByName() 函数中访问O(lg n)(只需在by_field 中查找),同时还保留插入顺序(只需在by_order 中查找)。

【讨论】:

  • 你不能做任何这样的事情,因为 ptr_map 和 ptr_vector 都拥有它们的元素数据。
  • 对不起,std::vector&lt;Node*&gt; 无论Node 的正确值是多少。这真的值得投反对票吗?
  • 我不明白为什么不这样做。由于我指出的原因,这是很多挥手的事情,而且顺便说一句也不正确。有更多优点的cmets
  • @Barry:也许将其编辑到答案中以使其至少没有明显错误,这将至少有机会消除反对票。
猜你喜欢
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多