map<string, string> dada;
dada["dummy"] = "papy";
cout << dada["pootoo"];
未定義の動作と見なされるかどうかがわからないため、困惑しています。存在しないキーを要求したときに、代わりに find を使用する方法を知る方法はありますか?
はmap::operator[]
、指定されたキーに対応する値のデータ構造を検索し、それへの参照を返します。
見つからない場合は、デフォルトの構成要素を透過的に作成します。(この動作を望まない場合は、map::at
代わりに関数を使用できます。)
ここで std::map のメソッドの完全なリストを取得できます。
http://en.cppreference.com/w/cpp/container/map
map::operator[]
これは、現在の C++ 標準のドキュメントです...
T& operator[](const key_type& x);
効果: マップに x に相当するキーがない場合、value_type(x, T()) をマップに挿入します。
必須: key_type は CopyConstructible であり、mapped_type は DefaultConstructible でなければなりません。
戻り値: *this の x に対応する mapping_type への参照。
複雑さ: 対数。
T& operator[](key_type&& x);
効果: マップに x に相当するキーがない場合、 value_type(std::move(x), T()) をマップに挿入します。
必須: mapping_type は DefaultConstructible でなければなりません。
戻り値: *this の x に対応する mapping_type への参照。
複雑さ: 対数。
key value
using インデックス演算子にアクセスしようとすると[]
、次の 2 つのことが発生する可能性があります。
key
ます。したがって、対応する が返されkey value
ます。key
。この場合、 を使用して自動的に をkey
マップに追加しnull value
ます。"pootoo"
キーがマップに存在しません。key
したがって、これはvalue = ""
(空の文字列)で自動的に追加されます。そして、あなたのプログラムは空の文字列を出力します。
ここで、マップのサイズが だけ大きくなり1
ます。
キーを検索するには、キーが存在しない場合map_name.find()
に返される を使用できます。map_name.end()
また、余分なkey
ものは追加されません。
[]
キーに値を設定する場合は、演算子を使用できます。
未定義の動作ではありません。operator []
指定されたキーの値が見つからない場合は、その位置に値を挿入します。
operator[] の場合、存在しないキーの値にアクセスしようとすると、デフォルトで構築された新しい値オブジェクトがマップに配置され、その参照が返されます。
operator[]
formap
は非 const 参照を返し、2 行目に示した方法でそれを使用して割り当てることができます。この方法でアクセスすると、タイプのデフォルトの構築要素が作成されますvalue
。
要素を見つけたい場合、より良い方法は
iterator find ( const key_type& x )
<map>.end()
(または const の代替)キーが見つからない場合、または使用できるコレクションにあるかどうかを知りたい場合に等しいイテレータを返します
size_type count ( const key_type& x ) const
キーは一意であるため、常にマップに対して 1 または 0 を返します。
operator [] が提供されたキーの値を見つけられない場合、その位置に値を挿入します。
ただし、にアクセスしてそのメンバー関数 (mapKV[not_exist_key].member_fun() など) を呼び出すと、プログラムがクラッシュする可能性があることに注意してください。not exist key
例を挙げましょう。以下のようにクラスをテストします。
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 に挿入するidName[5]
マップ構造を呼び出します。{5, MapValue(0)}
しかし、メンバー関数を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;
out_of_range 例外をご覧ください: http://www.cplusplus.com/reference/stdexcept/out_of_range/
これは、キーが存在しない場合に map::at および map::operator[] がスローするものです。リンクのベクトルの例と同じ方法でキャッチできます。
次も使用できます: http://www.cplusplus.com/reference/map/map/find/
そして map::end に対してチェックします