首页 > 解决方案 > 与 std::map 类型匹配的模板函数

问题描述

我的程序中有四个地图:

std::map< int, SigGen* > id_to_siggen_map;
std::map< int, std::vector< double > > id_to_ticks_map;
std::map< int, std::vector< double > > id_to_samples_map;
std::map< int, QListWidgetItem* > id_to_item_map;

我想编写一个模板函数,给定一个id,可以从上述任何映射中删除与该id对应的条目,即

int id = 4; //could be any other id number
delete_from_map(id, id_to_siggen_map); //deletes entry corresponding to id 4 from id_to_siggen_map
delete_from_map(id, id_to_ticks_map); //deletes corresponding entry from id_to_siggen_map
delete_from_map(id, id_to_samples_map);
delete_from_map(id, id_to_item_map); 

到目前为止我所拥有的:

template <typename T>
void delete_from_map(int id, std::map< int, T > mymap){
  for (auto it = mymap.begin(); it != mymap.end(); it++){
     if(it->first == id){
        mymap.erase(it);
        break;
     }
  }
}

但是,编译尝试给我四个地图中的每一个的未定义参考错误。错误如下所示:

error: undefined reference to `void DVis::delete_from_map<QListWidgetItem*>(int, std::map<int, QListWidgetItem*, std::less<int>, std::allocator<std::pair<int const, QListWidgetItem*> > >)'

我在这里做错了什么?

标签: c++

解决方案


首先,不需要像在 map 中那样使用 for 循环,您可以直接按值删除元素,其次,在 map 中迭代时删除不是一个好主意,因为它可能导致迭代器失效(检查:http://高级cpptopics.blogspot.com/)。正如 OP 指出并由其他人验证的那样,有问题的代码是正确的,但如果我们使用可变参数模板可能会更好,因为将来您可能会遇到编写自己的分配器等的情况。因此建议您尝试以下版本:

template<typename... Args>
void delete_from_map(int id,std::map<int,Args...>& m)
{
    m.erase(id);
}

推荐阅读