问题描述
我一直在接受 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 循环
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;
如果您没有为 operator <<
类型的对象定义 std::map
,则没有意义。
还有这个循环
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 ) );
}