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 ) );
}
我一直在进行一些 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 ) );
}