次のコードは、マップをconst
として_operator[]
_メソッドに渡すと、修飾子が破棄されることを示しています。
_#include <iostream>
#include <map>
#include <string>
using namespace std;
class MapWrapper {
public:
const int &get_value(const int &key) const {
return _map[key];
}
private:
map<int, int> _map;
};
int main() {
MapWrapper mw;
cout << mw.get_value(42) << endl;
return 0;
}
_
これは、マップアクセスで発生する可能性のある割り当てのためですか?マップアクセスを持つ関数はconstとして宣言できませんか?
MapWrapper.cpp:10: error: passing ‘const std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = int, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int> >]’ discards qualifiers
std::map
のoperator []
はconst
として宣言されておらず、その動作が原因ではありません:
T&operator [](const Key&キー)
Keyと同等のキーにマップされている値への参照を返します。そのようなキーがまだ存在しない場合は挿入を実行します。
その結果、関数はconst
として宣言できず、マップのoperator[]
を使用できます。
std::map
のfind()
関数を使用すると、マップを変更せずにキーを検索できます。
find()
は、iterator
、またはconst_iterator
を std::pair
キー(.first
)と値(.second
)の両方を含む。
C++ 11では、std::map
に at()
を使用することもできます。要素が存在しない場合、std::out_of_range
とは対照的に、関数はoperator []
例外をスローします。
_operator[]
_ にはconst修飾されたオーバーロードがないため、const修飾された関数では安全に使用できません。これはおそらく、現在のオーバーロードが、キー値を返すことと設定することの両方を目的として作成されたためです。
代わりに、次を使用できます。
_VALUE = map.find(KEY)->second;
_
または、C++ 11では、 at()
演算子を使用できます。
_VALUE = map.at(KEY);
_
const
のマップではoperator[]
を使用できません。このメソッドはマップを変更できるためconst
ではないためです(_map[key]
に割り当てることができます)。代わりにfind
メソッドを使用してみてください。
GCCヘッダーの新しいバージョン(私のマシンでは4.1および4.2)には、constが宣言され、キーがマップにない場合にstd :: out_of_rangeをスローする非標準メンバー関数map :: at()があります。
const mapped_type& at(const key_type& __k) const
関数のコメントの参照から、これが標準ライブラリの新しいメンバー関数として提案されているようです。
まず、_で始まるシンボルを使用しないでください。これらのシンボルは、言語の実装/コンパイラライター用に予約されています。 _mapが誰かのコンパイラの構文エラーになるのは非常に簡単であり、あなた自身のせいにする人はいません。
アンダースコアを使用する場合は、先頭ではなく末尾に配置します。おそらく、Microsoftのコードがそれを実行しているのを見て、この間違いを犯したのでしょう。覚えておいて、彼らは独自のコンパイラを書くので、彼らはそれで逃げることができるかもしれません。それでも、それは悪い考えです。
演算子[]は参照を返すだけでなく、実際にマップにエントリを作成します。したがって、マッピングを取得するだけでなく、マッピングがない場合はマッピングを作成します。それはあなたが意図したものではありません。