2011-06-16 110 views
4

这就是我通过map定义的方式。C++ STL map,std :: pair作为密钥

std::map<std::pair<std::string,std::string>, int> edMap; 

我很困惑如何插入值,我总是收到编译错误。 这就是我试图插入的方式。

std::pair<std::string,std::string> key; 
    edMap.insert(key,d); 

编译错误是

1>------ Build started: Project: spellsuggest, Configuration: Debug Win32 ------ 
1>Compiling... 
1>breathalyzer.cpp 
1>d:\personal\spellsuggest\spellsuggest\breathalyzer.cpp(70) : error C2664: 'std::_Tree<_Traits>::iterator std::_Tree<_Traits>::insert(std::_Tree<_Traits>::iterator,const std::pair<_Ty1,_Ty2> &)' : cannot convert parameter 1 from 'std::pair<_Ty1,_Ty2>' to 'std::_Tree<_Traits>::iterator' 
1>  with 
1>  [ 
1>   _Traits=std::_Tmap_traits<std::pair<std::string,std::string>,int,std::less<std::pair<std::string,std::string>>,std::allocator<std::pair<const std::pair<std::string,std::string>,int>>,false>, 
1>   _Ty1=const std::pair<std::string,std::string>, 
1>   _Ty2=int 
1>  ] 
1>  and 
1>  [ 
1>   _Ty1=std::string, 
1>   _Ty2=std::string 
1>  ] 
1>  and 
1>  [ 
1>   _Traits=std::_Tmap_traits<std::pair<std::string,std::string>,int,std::less<std::pair<std::string,std::string>>,std::allocator<std::pair<const std::pair<std::string,std::string>,int>>,false> 
1>  ] 
1>  No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 
1>Build log was saved at "file://d:\personal\spellsuggest\spellsuggest\Debug\BuildLog.htm" 
1>spellsuggest - 1 error(s), 0 warning(s) 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 
+0

为了将来的参考,当您就Stack Overflow提出提及编译器错误的问题时,请务必将实际的编译器错误消息逐字地包含(即复制并粘贴)到您的文章中。我们是人类,而不是编译器。 – 2011-06-16 12:23:35

+2

与问题绝对没有关系 - 但我对一个名为“spellsuggest”的项目(?)内名为“breathalyzer.cpp”的文件很感兴趣。 – Chowlett 2011-06-16 12:33:05

+0

@Chowlett :)从一些东西开始,现在开始。小傻瓜。 – Avinash 2011-06-16 12:36:44

回答

13

让我们尝试:

typedef std::pair<std::string, std::string> my_key_type; 
typedef std::map<my_key_type, int>   my_map_type; 

my_map_type m; 

m.insert(my_map_type::value_type(my_key_type("A", "B"), 43)); 

观察该地图的value_type总是std::pair<const key_type, mapped_type>,所以你的情况是std::pair<my_key_type, int> - 一对,其第一件本身就是一对!

考虑到这一点,你可以选择使用make_pair

m.insert(std::make_pair(my_key_type("C", "D"), -5)); 

最后,斯文指出,有可能会或可能不会是对的比较操作符(我认为有,虽然);所以如果没有,你必须自己写一个。这两个元素的词典比较应该做。苏菲等待:-)

(这里的字典对比较; 你不需要写这篇文章,它已经存在 :)

template<typename S, typename T> 
bool operator<(const std::pair<S, T> & a, const std::pair<S, T> & b) 
{ 
    return (a.first < b.first) || (a.first == b.first && a.second < b.second); 
} 
+0

有一个,我误了;我已经编辑了我的答案。 – Sven 2011-06-16 12:31:27

+0

@Sven:干杯,我只是提到比较,然后给出一个想法。 – 2011-06-16 12:33:47

+1

无论如何,向名称空间std添加'operator <'是无效的。如果你需要,你可以专注于'std :: less'。 – 2011-06-16 13:52:25

3

插入方法需要一个完整的对地图的类型,所以你必须要做到这一点:

edMap.insert(make_pair(key, d)); 
+0

而这是一个“痛苦”!不是C++ 0x中的新“emplace”。 – 2011-06-16 12:31:27

0

需要注意的是这样的:

std::pair<std::string,std::string> key; 
edMap.insert(make_pair(key,d)); 

将无法​​插入任何东西,如果已经有一个键存在相同的值。

这在另一方面:

std::pair<std::string,std::string> key; 
edMap[key] = d; 

要么在地图上创建一个新的项目,或覆盖以前的值,如果存在。