如何使用迭代器擦除 std::list 模板

Posted

技术标签:

【中文标题】如何使用迭代器擦除 std::list 模板【英文标题】:how to erase with iterator for std::list template 【发布时间】:2019-12-02 12:44:42 【问题描述】:

我正在尝试了解迭代器的工作原理。

我已经构建了以下代码:

list<Bucket<Key,Val>> *array;

template<typename Key, typename Val>
class Bucket

public:
    Bucket(Key key, Val value)
    
        this->key = key;
        this->value = value;
    

    ~Bucket()

    const Key getKey() const
    
        return key;
    

    const Val getValue() const
    
        return value;
    

private:
    Key key;
    Val value;
;

在其中一个列表中插入存储桶后,我想至少执行 2 个操作: 查找和删除。

我可以使用此代码查找给定值:

    int entryNum = HashFunc()(key);

    for(auto i: array[entryNum % capacity])
    
        if(MatchFunc(i.getKey(),key)())
        
            value = i.getValue();
        
    

但我似乎无法通过添加类似的内容来删除项目 i = 数组[entryNum % 容量].erase(i); 或删除。 但如果我这样做,它会起作用:

    int entryNum = HashFunc()(key);
    typename list<Bucket<Key,Val>>::iterator it;

    for(auto i: array[entryNum % capacity])
    
        ++testcounter;
        if(MatchFunc(i.getKey(),key)())
        
            value = i.getValue();
        
    

    for (it=array[entryNum % capacity].begin(); it!= array[entryNum % capacity].end(); ++it)
    
        if(testcounter!=0) --testcounter;
        else
        
            array[entryNum % capacity].erase(it);
            return htKeyFound;
        
    

这显然不理想,我不想在同一个列表上重复两次 + 为它保留一个计数器。但我似乎无法将它们合二为一。 当我尝试访问 it.getKey() 时,它显然不起作用并出现编译错误。 关于我做错了什么有什么建议吗?

【问题讨论】:

【参考方案1】:

Range for loops 迭代容器内的

std::list::erase 函数需要一个迭代器,而不是一个值。


而且你不需要两个循环,你可以取消引用一个迭代器来获得它“指向”的值:

int entryNum = HashFunc()(key);

auto& list_ref = array[entryNum % capacity];
for(auto it = list_ref.begin(); it != list_ref.end(); ++it)

    if(MatchFunc(it->getKey(),key)())
    
        value = it->getValue();
        list_ref.erase(it);
        return htKeyFound;
    

【讨论】:

好吧,伙计,它成功了! :) 非常感谢您,但我会提到参考线是'auto& list_ref'。否则它不会编译 - 再次 不客气。但请花点时间阅读What should I do when someone answers my question?

以上是关于如何使用迭代器擦除 std::list 模板的主要内容,如果未能解决你的问题,请参考以下文章

迭代 std::list 时擦除

我可以在 std::list 中移动元素而不会使迭代器或引用无效,但是如何?

给定迭代器替换 std::list 对象

从 Map 擦除后访问指针

使用指向值的原始指针从 std::list<Value> 中擦除?

如何使用 OpenMP 通过 C++ std::list 并行化 for 循环?