2017-06-13 106 views
3
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? 

客户机从管理器/分派器获取新实例的“读取器”对象。如果“每个人都感兴趣”通过观察所分派的读者群来捡起它,那么经理会维护一个被分派的内部列表,并使缓存的数据无效/释放。通过引用从std :: list中删除元素

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

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

+0

是t hese'读者'唯一(没有'读者'具有相同的值)? – NathanOliver

+0

@NathanOliver:是的。每个客户端都有一个独特的阅读器,通过方法从缓存中选择数据(并将其标记为“已被此用户使用”),如果所有感兴趣的用户都“用完了”,那么经理会使数据无效。 –

+0

'readers.remove(r);'应该工作(如果'r'是唯一的),但会内部迭代列表。 –

回答

3

你的选择,如果你只需要对对象的引用是使用std::list::remove

readers.remove(r); 

std::find连同std::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

使用std::remove结合erase

readers.erase(std::remove(readers.begin(), readers.end(), r), readers.end()); 

而且,你无法从列表中删除价值元素,不反复它。如果你仔细想想,它甚至没有什么意义,因为列表中的指针必须更新为

+0

'remove'实际上在这种情况下被删除,因此无法编译,因为它返回'void'。 – NathanOliver

+0

这不会找到正是这个元素,但任何元素是平等可比的...你必须比较elems指针... – ovanes

+0

是的弥恩,我的坏,我更新了答案 –

2

你可以比较指针,以检查它们是否相同的对象

readers.remove_if([r=&r](auto& x){return &x==r;}); 
+1

删除期望一个值,它可以比较列表中的项目。很确定这不会编译 – NathanOliver

+1

也许你的意思是'remove_if'而不是'remove'? – Akira

+0

更改'remove'到'remove_if',你有最酷的解决方案! – ovanes

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