2

C++ 標準ライブラリの std::map クラスをいじってみると、要素を消去してから参照しようとすると (以下のコードのコメントアウトされた行)、要素が値 0 で返されることに気付きました。 ? 要素が存在しない場合に誤って要素を作成することなく、要素にアクセスするために検索機能を使用する必要がありますか?

コンパイラのセットアップ: g++ i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 を使用して osx 10.8.3 でコンパイルしています (Apple Inc. ビルド 5658 に基づく) (LLVM ビルド 2336.11.00)

using namespace std;

map<int,int> myMap;
map<int,int>::iterator it;

myMap[1] = 5;

for (it=myMap.begin(); it!=myMap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

printf("map test result: %d\n", myMap[1]);

it = myMap.find(1);
myMap.erase( it );

// If I uncomment this it will cause a 0 value to occur at key 1.
//printf("map test result: %d\n", myMap[1]);

if (myMap.find(1) == myMap.end())
    puts("element key 1 is null, ok");
else
    puts("element @ key 1 exists, error");

if (myMap.empty())
    puts("map is empty");
else
    puts("map is not empty, error");

for (it=myMap.begin(); it!=myMap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

明確にするために、2 番目の printf 行をコメントにしてこれを実行すると、期待どおりに実行されます。

1 => 5
map test result: 5
element key 1 is null, ok
map is empty

行のコメントを外して実行すると、printf ステートメントで myMap[1] にアクセスすると、別の要素が作成され、次の結果が残ります。

1 => 5
map test result: 5
map test result: 0
element @ key 1 exists, error
map is not empty, error
1 => 0
4

2 に答える 2

5

はい、これがoperator[]of のstd::mapすべきことです。標準から (C++11、§23.5.4.3):

mapped_type& operator[](const key_type& k);
mapped_type& operator[](key_type&& k);

[...]

効果: unordered_map に k と等しいキーを持つ要素がまだ含まれていない場合、最初の演算子は値value_type(k, mapped_type())を挿入し、2 番目の演算子は値を挿入しますvalue_type(std::move(k), mapped_type())

これは、要素が挿入されてから消去されていない場合でも発生することに注意してください。を使用した要素アクセスoperator[]は、存在しないキーに適用すると、デフォルトで構築された新しい値を挿入するだけです。

これを望まない場合は、 のfind機能を使用することをお勧めしますstd::mapendキーが存在しない場合、これは -iterator を返します。

于 2013-06-11T04:24:03.500 に答える