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

未定義の動作と見なされるかどうかがわからないため、困惑しています。存在しないキーを要求したときに、代わりに find を使用する方法を知る方法はありますか?

4

7 に答える 7

111

map::operator[]、指定されたキーに対応する値のデータ構造を検索し、それへの参照を返します。

見つからない場合は、デフォルトの構成要素を透過的に作成します。(この動作を望まない場合は、map::at代わりに関数を使用できます。)

ここで std::map のメソッドの完全なリストを取得できます。

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

map::operator[]これは、現在の C++ 標準のドキュメントです...

23.4.4.3 マップ要素へのアクセス

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

  1. 効果: マップに x に相当するキーがない場合、value_type(x, T()) をマップに挿入します。

  2. 必須: key_type は CopyConstructible であり、mapped_type は DefaultConstructible でなければなりません。

  3. 戻り値: *this の x に対応する mapping_type への参照。

  4. 複雑さ: 対数。

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

  1. 効果: マップに x に相当するキーがない場合、 value_type(std::move(x), T()) をマップに挿入します。

  2. 必須: mapping_type は DefaultConstructible でなければなりません。

  3. 戻り値: *this の x に対応する mapping_type への参照。

  4. 複雑さ: 対数。

于 2012-04-12T13:34:38.077 に答える
28

key valueusing インデックス演算子にアクセスしようとすると[]、次の 2 つのことが発生する可能性があります。

  1. マップにはこれが含まれていkeyます。したがって、対応する が返されkey valueます。
  2. マップには が含まれていませんkey。この場合、 を使用して自動的に をkeyマップに追加しnull valueます。

"pootoo"キーがマップに存在しません。keyしたがって、これはvalue = ""(空の文字列)で自動的に追加されます。そして、あなたのプログラムは空の文字列を出力します。

ここで、マップのサイズが だけ大きくなり1ます。

キーを検索するには、キーが存在しない場合map_name.find()に返される を使用できます。map_name.end()また、余分なkeyものは追加されません。

[]キーに値を設定する場合は、演算子を使用できます。

于 2014-12-20T13:18:09.797 に答える
9

未定義の動作ではありません。operator []指定されたキーの値が見つからない場合は、その位置に値を挿入します。

于 2012-04-12T13:35:29.650 に答える
7

operator[] の場合、存在しないキーの値にアクセスしようとすると、デフォルトで構築された新しい値オブジェクトがマップに配置され、その参照が返されます。

于 2012-04-12T13:35:12.707 に答える
3

operator[]formapは非 const 参照を返し、2 行目に示した方法でそれを使用して割り当てることができます。この方法でアクセスすると、タイプのデフォルトの構築要素が作成されますvalue

要素を見つけたい場合、より良い方法は

iterator find ( const key_type& x )

<map>.end()(または const の代替)キーが見つからない場合、または使用できるコレクションにあるかどうかを知りたい場合に等しいイテレータを返します

size_type count ( const key_type& x ) const

キーは一意であるため、常にマップに対して 1 または 0 を返します。

于 2012-04-12T13:44:16.570 に答える
1

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;
于 2018-11-15T12:45:22.447 に答える
0

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 に対してチェックします

于 2013-08-16T13:55:11.260 に答える