map<string, string> dada;
dada["dummy"] = "papy";
cout << dada["pootoo"];
我很困惑,因为我不知道它是否被认为是未定义的行为,如何知道我何时请求不存在的密钥,我只是使用find吗?
答案 0 :(得分:59)
map::operator[]
在数据结构中搜索与给定键对应的值,并返回对它的引用。
如果找不到它,它会透明地为它创建一个默认的构造元素。 (如果您不想要此行为,则可以使用map::at
函数。)
您可以在此处获取std :: map方法的完整列表:
http://en.cppreference.com/w/cpp/container/map
以下是当前C ++标准中map::operator[]
的文档......
T& operator[](const key_type& x);
效果:如果地图中没有等效于x的键,请将value_type(x,T())插入地图中。
要求:key_type应为CopyConstructible,mapped_type应为DefaultConstructible。
返回:对* this中x对应的mapped_type的引用。
复杂性:对数。
T& operator[](key_type&& x);
效果:如果地图中没有等效于x的键,则将value_type(std :: move(x),T())插入到地图中。
要求:mapped_type应为DefaultConstructible。
返回:对* this中x对应的mapped_type的引用。
复杂性:对数。
答案 1 :(得分:14)
如果您尝试使用索引运算符key value
访问[]
,则可能会发生以下两种情况:
key
。因此它将返回相应的key value
。key
。在这种情况下,它会自动使用key
向地图添加null value
。 "pootoo"
密钥不存在于您的地图中。因此,它会自动添加key
value = ""
(空字符串)。并且您的程序将打印空字符串。
此处地图尺寸将增加1
。
要搜索密钥,您可以使用map_name.find()
,如果密钥不存在,将返回map_name.end()
。并且不会添加额外的key
。
如果要为密钥设置值,可以使用[]
运算符。
答案 2 :(得分:7)
这不是未定义的行为。如果operator []
找不到所提供键的值,则会在该位置插入一个值。
答案 3 :(得分:6)
对于operator [],如果您尝试访问不存在的键的值,则默认构造的新值对象将被放入地图并返回它的引用。
答案 4 :(得分:2)
operator[]
map
会返回非const引用,您可以按照第二行显示的方式使用该引用进行分配。以这种方式访问将创建value
类型的默认构造元素。
如果你想找到一个元素,一个更好的方法是
iterator find ( const key_type& x )
(或const替代)如果找不到密钥将返回等于<map>.end()
的迭代器,或者如果你只是想知道它是否在集合中你可以使用
size_type count ( const key_type& x ) const
对于地图将始终返回1或0,因为键是唯一的。
答案 5 :(得分:1)
如果运算符[]找不到所提供键的值,则会在该位置插入一个。
但是您应该注意,如果您访问not exist key
并调用它的成员函数,例如mapKV [not_exist_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, does't crash-------"<<endl;
答案 6 :(得分:0)
请查看out_of_range异常: http://www.cplusplus.com/reference/stdexcept/out_of_range/
如果key不存在,这就是map :: at和map :: operator []将抛出的内容。您可以像链接中的矢量示例一样捕获它。
您还可以使用: http://www.cplusplus.com/reference/map/map/find/
并检查map :: end