次のようなmap
という名前のvalueMap
があります。
typedef std::map<std::string, std::string>MAP;
MAP valueMap;
...
// Entering data.
次に、このマップを参照により関数に渡します。
void function(const MAP &map)
{
std::string value = map["string"];
// By doing so I am getting an error.
}
関数への参照として渡されるマップから値を取得するにはどうすればよいですか?
残念ながら_std::map::operator[]
_は非constメンバー関数であり、const参照があります。
function
の署名を変更するか、次のいずれかを実行する必要があります。
_MAP::const_iterator pos = map.find("string");
if (pos == map.end()) {
//handle the error
} else {
std::string value = pos->second;
...
}
_
_operator[]
_は、デフォルトの構築値をマップに追加し、その参照を返すことでエラーを処理します。あなたが持っているのがconst参照だけである場合、これは役に立たないので、何か違うことをする必要があります。
プログラムのロジックが何らかの理由で_"string"
_がすでにキーであることを保証している場合、could可能性を無視してstring value = map.find("string")->second;
を記述します。明らかな問題は、間違っていると未定義の動作が発生することです。
map.at( "key")は、キーがない場合に例外をスローします
Kがコンテナ内のどの要素のキーとも一致しない場合、関数はout_of_range例外をスローします。
answer bySteve Jessopは、std::map::operator[]
でconst std::map
を使用できない理由を説明しています。 Gabe Rainbow'sanswer は、ニースの代替案を示唆しています。 map::at()
の使用方法に関するサンプルコードを提供したいだけです。したがって、以下はfunction()
の拡張例です。
void function(const MAP &map, const std::string &findMe) {
try {
const std::string& value = map.at(findMe);
std::cout << "Value of key \"" << findMe.c_str() << "\": " << value.c_str() << std::endl;
// TODO: Handle the element found.
}
catch (const std::out_of_range&) {
std::cout << "Key \"" << findMe.c_str() << "\" not found" << std::endl;
// TODO: Deal with the missing element.
}
}
次に、main()
関数の例を示します。
int main() {
MAP valueMap;
valueMap["string"] = "abc";
function(valueMap, "string");
function(valueMap, "strong");
return 0;
}
出力:
キー "string"の値:abc
キー「strong」が見つかりません
関数への参照として渡されるマップから値を取得するにはどうすればよいですか?
参照として渡すことができます。 標準参照ラッパー つまり。
typedef std::map<std::string, std::string> MAP;
// create your map reference type
using map_ref_t = std::reference_wrapper<MAP>;
// use it
void function(map_ref_t map_r)
{
// get to the map from inside the
// std::reference_wrapper
// see the alternatives behind that link
MAP & the_map = map_r;
// take the value from the map
// by reference
auto & value_r = the_map["key"];
// change it, "in place"
value_r = "new!";
}
そしてテスト。
void test_ref_to_map() {
MAP valueMap;
valueMap["key"] = "value";
// pass it by reference
function(valueMap);
// check that the value has changed
assert( "new!" == valueMap["key"] );
}
これはナイスでシンプルだと思います。楽しい ...