C++ 断言失败:无法递增值初始化 map/set 迭代器

C++ Assertion Failed: cannot increment value-initialized map/set iterator

我一直在进行一些 C++ 培训,上次我尝试 运行 在另一台计算机上编写我的代码。在那里,我在调试中构建,并且由于断言失败而停止执行。我正在操作容器,当我使用地图时,似乎无法删除元素。 removeItem() 方法正在触发断言,但我不明白为什么。

主要:

int main()
{
    // Exercice 4.1   Map and strings
    std::list<std::string> list = {"eggs", "milk", "sugar", "chocolate", "flour"};
    CMapStrings mapStrings;
    mapStrings.print();
    mapStrings.addItem(list);
    mapStrings.print();
    mapStrings.addItem("coffee");
    mapStrings.print();
    mapStrings.replaceItem("sugar", "honey");
    mapStrings.print();
    mapStrings.removeItem("milk");  //buggy
    mapStrings.print();
    std::cout << std::endl; 
}

Hpp:

class CMapStrings
{
public:
    CMapStrings();

    void print();

    void addItem(std::string f_item);

    void addItem(std::list<std::string> f_items);

    void removeItem(std::string f_item);

    void removeLastItem();

    void replaceItem(std::string f_previousItem, std::string f_nextItem);

private:
    std::map<int, std::string> m_shoppingList2;
};

Cpp:

CMapStrings::CMapStrings()
{
}

void CMapStrings::addItem(std::string f_item)
{
    m_shoppingList2.insert(std::pair<int, std::string>(m_shoppingList2.size(), f_item));
}

void CMapStrings::addItem(std::list<std::string> f_items)
{
    for (std::uint32_t i = 0; i < f_items.size(); i++)
    {
        auto l_front = f_items.begin();
        std::advance(l_front, i);
        m_shoppingList2.insert(std::pair<int, std::string>(i, *l_front));
    }
}

void CMapStrings::removeItem(std::string f_item)
{
    for(auto it = m_shoppingList2.begin(); it != m_shoppingList2.end(); it++)
    {
        if(it->second == f_item)
        {
            m_shoppingList2.erase(it->first);
        }
    }
}

void CMapStrings::replaceItem(std::string f_previousItem, std::string f_nextItem)
{
    for(auto it = m_shoppingList2.begin(); it != m_shoppingList2.end(); it++)
    {
        if(it->second == f_previousItem)
        {
            it->second = f_nextItem;
        }
    }
}

void CMapStrings::print()
{
    std::cout << "shopping list size (map): " << m_shoppingList2.size() << std::endl;
    std::cout << m_shoppingList2 << std::endl;
}

为循环重写这个

for(auto it = m_shoppingList2.begin(); it != m_shoppingList2.end(); it++)
{
    if(it->second == f_item)
    {
        m_shoppingList2.erase(it->first);
    }
}

以下方式

for(auto it = m_shoppingList2.begin(); it != m_shoppingList2.end(); )
{
    if(it->second == f_item)
    {
        it = m_shoppingList2.erase(it);
    }
    else
    {
        ++it;
    }
}

注意这条语句

std::cout << m_shoppingList2 << std::endl;
如果您没有为 std::map.

类型的对象定义 operator <<

没有任何意义

而这个循环

for (std::uint32_t i = 0; i < f_items.size(); i++)
{
    auto l_front = f_items.begin();
    std::advance(l_front, i);
    m_shoppingList2.insert(std::pair<int, std::string>(i, *l_front));
}

效率低下。您可以使用基于范围的 for 循环,例如

int i = 0;

for ( const auto &s : f_items )
{
    m_shoppingList2.insert(std::pair<int, std::string>( i++, s ) );
}