2012-01-10 52 views
1

我在C++映射一个基本的查询,C++地图添加了新的元素

map<char,string> mymap; 

    mymap['a']="an element"; 
    mymap['b']="another element"; 
    mymap['c']=mymap['b']; 

    cout << "mymap['a'] is " << mymap['a'] << endl; 
    cout << "mymap['b'] is " << mymap['b'] << endl; 
    cout << "mymap['c'] is " << mymap['c'] << endl; 
    cout << "mymap['d'] is " << mymap['d'] << endl; 

,当我们试图访问MyMap中[“d”],我得到一个默认值,因为操作员将在一个新元素使用该键映射并初始化为其默认值,即使仅访问它以检索其值。下一次当我使用迭代器时,我可以看到键'd'的空值。有什么方法可以限制地图插入默认值。

+0

你是怎么想到* *当你写'MyMap中[ 'd']'发生? – 2012-01-10 16:52:08

+2

如果您从http://www.cplusplus.com/reference/stl/map/operator%5B%5D/逐字记下了该代码,那么提起它就会很礼貌。特别是因为该页面构成并回答你的问题。 “ 注意最后一次访问(对于元素'd')如何使用该键在映射中插入一个新元素,并将其初始化为其默认值(空字符串),即使只访问它以检索其值。成员函数map: :发现不会产生这种效果。“ – 2012-01-10 16:55:41

回答

8

如果您不想使用默认插入,则应该使用map.find而不是operator []

map::find

iterator find (const key_type& x); 
const_iterator find (const key_type& x) const; 

搜索具有x作为键的元素的容器,如果找到返回迭代到它,否则返回一个迭代映射::端(过去的端部的元件容器)

1

这是std::map的预期和记录的行为。为了检查某个项目的存在,请使用find

0
map<char, string>::iterator mIte = mymap.find('d'); 
if(mIte != mymap.end()) 
cout << "mymap['d'] is " << mIte->second << endl; 
else 
cout << "mymap['d'] is empty" << endl; 
1

使用map的成员函数iterator find(const key_type& k)仅用于查询。 地图的操作符[]有一些“特殊效果”

data_type& operator[](const key_type& k) 

返回对与特定键相关联的对象的引用。如果地图尚未包含这样的对象,则operator []将插入默认对象data_type()。 [3]

更多参考可在 http://www.sgi.com/tech/stl/Map.html

0

发现这不仅是该记录的行为,但有一点想法很容易明白为什么。索引操作只有两个明智的结果:或者返回地图中的有效条目,或者抛出异常。如果您不抛出异常,那么唯一的选择是创建一个新条目。我不知道为什么标准选择了另一个,但事实就是如此。

Microsoft提供了一个抛出而不是创建元素的at方法,但这看起来不在标准或gcc中。

可以很容易地创建一个使用find做同样的事情的函数:

template<typename Key, typename Value> 
Value& at(std::map<Key,Value> & the_map, const Key & the_key) 
{ 
    std::map<Key,Value>::iterator it = the_map.find(the_key); 
    if (it == the_map.end()) 
     throw std::out_of_range("map index invalid"); 
    return it->second; 
} 

template<typename Key, typename Value> 
const Value& at(const std::map<Key,Value> & the_map, const Key & the_key) 
{ 
    std::map<Key,Value>::const_iterator it = the_map.find(thekey); 
    if (it == the_map.end()) 
     throw std::out_of_range("map index invalid"); 
    return it->second; 
} 
+0

'map :: at'在C++ 11中定义,GCC仅支持最新版本,如果您要求(使用'-std = C++ 0x'或'-std = C++ 11' )。 – 2012-01-10 18:27:06

0

operator[]总会插入一个默认值,如果关键是尚未在地图上。

在C++ 11中,mymap.at('d')将抛出out_of_range,并且不插入默认值。

在C++ 03,你可以用find效仿:

template <typename Key, typename Value, typename C, typename A> 
Value at(std::map<Key,Value,C,A> const & map, Key const & key) 
{ 
    typename std::map<Key,Value,C,A>::const_iterator found = map.find(key); 
    if (found == map.end()) { 
     throw std::out_of_range("at(map,key)"); 
    } 
    return found->second; 
}