What happens if I read a map's value where the key does not exist?

map<string, string> dada;
dada["dummy"] = "papy";
cout << dada["pootoo"];

I'm puzzled because I don't know if it's considered undefined behaviour or not, how to know when I request a key which does not exist, do I just use find instead ?

111737 次浏览

map::operator[]在数据结构中搜索与给定键对应的值,并返回对它的引用。

If it can't find one it transparently creates a default constructed element for it. (If you do not want this behaviour you can use the map::at function instead.)

您可以在这里获得 std: : map 方法的完整列表:

Http://en.cppreference.com/w/cpp/container/map

下面是来自当前 C + + 标准的 map::operator[]文档..。

23.4.4.3地图元素访问

T& operator[](const key_type& x);

  1. 效果: 如果映射中没有等效于 x 的键,那么将 value _ type (x,T ())插入映射中。

  2. 要求: key _ type 应该是可复制构造的,map _ type 应该是可默认构造的。

  3. 返回: 对映射 _ type 的引用,对应于 * this 中的 x。

  4. Complexity: logarithmic.

T& operator[](key_type&& x);

  1. Effects: If there is no key equivalent to x in the map, inserts value_type(std::move(x), T()) into the map.

  2. 要求: map _ type 应该是 DefaultConstruction。

  3. 返回: 对映射 _ type 的引用,对应于 * this 中的 x。

  4. 复杂度: 对数。

对于操作符[] ,如果您试图访问一个不存在的键的值,那么默认构造的新值对象将被放入映射并返回它的引用。

这不是未定义行为,如果 operator []没有找到所提供的键的值,它会在那个位置插入一个值。

operator[] for map返回一个非常量引用,您可以按照在第二行中显示的方式使用它进行赋值。以这种方式访问将创建 value类型的默认构造元素。

如果您想找到一个元素,一个更好的方法是

iterator find ( const key_type& x )

(或 const 选项) ,如果它没有找到键,或者如果您只是想知道它是否在集合中,您可以使用它,那么它将返回一个等于 <map>.end()的迭代器

size_type count ( const key_type& x ) const

因为键是唯一的,所以对于 map,它总是返回1或0。

请看一下超出范围的异常: Http://www.cplusplus.com/reference/stdexcept/out_of_range/

如果键不存在,map: : at 和 map: : Operator []将抛出这些内容。您可以使用与链接中的向量示例相同的方法来捕捉它。

You can also use: Http://www.cplusplus.com/reference/map/map/find/

然后对照 map: : end

如果您尝试使用索引操作符 []访问 key value,那么会发生以下两种情况:

  1. The map contains this key. So it will return the corresponding key value.
  2. 这个映射不包含 key。在这种情况下,它将自动使用 null value向映射添加一个 key

"pootoo"密钥在您的地图中不存在。因此,它将自动添加这个 keyvalue = ""(空字符串)。程序将打印空字符串。

这里的地图大小将增加 1

To search a key you can use map_name.find(), which will return map_name.end() if the key doesn't exist. And no extra key will be added.

当您想为键设置值时,可以使用 []运算符。

如果操作符[]没有找到所提供的键的值,它将在该位置插入一个值。

但是如果你访问一个 not exist key并调用它的成员函数,比如 mapKV [ not _ live _ key ] . member _ fun () ,程序可能会崩溃。

让我举个例子,测试类如下:

struct MapValue{
int val;


MapValue(int i=0){
cout<<"ctor: "<<i<<endl; val = i;
}


~MapValue(){
cout<<"dtor: "<<val<<endl;
}


friend ostream& operator<<(std::ostream& out, const MapValue& mv){
cout<<"MapValue: "<<mv.val<<endl;
}


string toString(){
cout<<"MapValue: "<<val<<endl;
}
};

测试代码:

cout<<"-------create map<int, MapValue>-------"<<endl;


map<int, MapValue> idName\{\{1, MapValue(1)}, {2, MapValue(2)}};


cout<<"-----cout key[2]-----"<<endl;
cout<<idName[2]<<endl;


cout<<"-----cout key[5]-----"<<endl;
cout<<idName[5]<<endl;


cout<<"------- runs here means, does't crash-------"<<endl;

产出如下:

-------create map<int, MapValue>-------
ctor: 1
ctor: 2
dtor: 2
dtor: 1
dtor: 2
dtor: 1
-----cout key[2]-----
MapValue: 2


-----cout key[5]-----
ctor: 0
MapValue: 0


-------runs here means, does't crash-------
dtor: 0
dtor: 2
dtor: 1

我们可以看到: idName[5]调用映射构造 {5, MapValue(0)}来插入 idName。

但是,如果通过 idName[5]调用成员函数,那么程序就会崩溃:

cout<<"-------create map<int, MapValue>-------"<<endl;


map<int, MapValue> idName\{\{1, MapValue(1)}, {2, MapValue(2)}};




idName[5].toString();  // get crash here.




cout<<"------- runs here means, doesn't crash-------"<<endl;