通过引用从std :: list中删除元素

时间:2017-06-13 15:20:17

标签: c++ reference stdlist

std::list<Reader> readers;

readers.push_back(Reader());

Reader& r = *(readers.begin());

/* at this point, the exact place in list, where the reader was picked out, is forgotten. 
   Only 'r' shows which element of the list it is. */

readers.erase(r); //<---how to do this?

客户获得新实例&#39;读者&#39;来自经理/调度员的对象。管理器维护一个内部列表,其中包含已分派的内容,如果&#34;每个人都感兴趣,则会使缓存的数据无效/释放。通过观察派遣的读者群来捡起它。

当客户端不再对数据感兴趣时,它应该将读取器返回给管理器以从池中删除。但我不希望客户保留一个迭代器 - 它对管理者和读者群的胆量绝对不感兴趣;它只需要这个自己的读者,而不是指向它的迭代器。因此,对于删除,它会调用管理器的清理功能,并引用该单个阅读器。

是否有更好的方法从列表中删除该阅读器,而不是遍历整个列表以搜索引用所引导的那个阅读器?

4 个答案:

答案 0 :(得分:3)

std::removeerase

结合使用
readers.erase(std::remove(readers.begin(), readers.end(), r), readers.end());

此外,你无法通过值从列表中删除元素,而无需迭代它。如果你考虑它,它甚至没有意义,因为列表中的指针必须更新。

答案 1 :(得分:3)

如果您只有对象的引用,则使用std::list::remove

readers.remove(r);

std::findstd::list::erase

一起使用
readers.erase(std::find(readers.begin(), readers.end(), r));

前者必须遍历整个列表,而后者在找到第一个元素时将停止,然后将其删除。对于大型列表,这可以产生很大的不同。

这两个选项仅在项目唯一时才有效。如果您有非唯一元素,那么您可以使用std::find_if并提供一个比较项目地址的仿函数。这样你就可以保证你只删除引用实际引用的对象,而不是比较等于。

readers.erase(std::find_if(readers.begin(), readers.end(), [&](const auto& e) {return &r == &e;}));

答案 2 :(得分:2)

您可以比较指针以检查它们是否是同一个对象

const uintFoo = 0x7ff8c0c0ac0ffee1

func ConstFoo() float64 {
    return math.Float64frombits(uintFoo)
}

答案 3 :(得分:1)

如果列表可以包含相等的值,那么您可以执行以下操作

#include <iostream>
#include <list>

int main()
{
    struct Reader { std::pair<char, int> p; };
    std::list<Reader> readers;

    readers.push_back({{ 'A', 1 } });
    readers.push_back({ { 'A', 2 } });
    Reader &rr = readers.back();
    readers.push_back({ { 'A', 3 } });

    readers.remove_if([&rr](const Reader &r) { return &r == &rr; });

    for (const auto &r : readers)
    {
        std::cout << r.p.first << ' ' << r.p.second << std::endl;
    }

    return 0;
}

程序输出

A 1
A 3