この質問の序文として、私はJavaプログラマーであるため、C++よりもJava)のマップのセマンティクスにはるかに慣れていると言わなければなりません。 。Javaでは非常に一般的であり、マップでキーを検索するとnull
が返されると予想されます。コードの一部をc ++に変換し、 unordered_mapと対話するときに物事を行うc ++の方法。
具体的には、unordered_mapを含むクラスがあります。マップをクライアントコードに直接公開する代わりに、2つのラッパー関数があります。1つはキーと値のペアをマップに配置し、もう1つは指定されたキーの値を取得します。
_void set_tag_value(string tag, string value);
string& get_tag_value(string tag);
_
unordered_map.at()
を使用して値を取得すると、コードがキャッチする必要のある例外がスローされるか、クライアントコードに伝播できるようになります。 (ただし、例外を伝播することは私には不親切に思えます)。
おそらく、戻り値を_string*
_タイプに変更し、見つからない場合はNULLを返す(Java方法))が、ユーザーは次のことを行う必要があります。 NULLをチェックします(これもそれほど友好的ではありません)。
したがって、私の質問には2つの部分があります。
失敗したルックアップを処理するための開発者にとって使いやすい方法は何ですか?また、どのような戻り値が役立ちますか(例外、NULL、空の文字列、またはその他)?
私のコード内では、キーが見つからない、at()で例外をキャッチする、またはイテレータ== map.end()を見つけてチェックすることが予想される場合に、どのマップルックアップメソッドを使用するのが一般的ですか? (質問のこの部分は、私がc ++のやり方を学ぼうとしているだけです)。
アドバイスありがとうございます!
私の意見では、マップが変更されるとポインタが無効になる可能性があるため、非公開にしているマップのコンテンツへのポインタを返さないことが最善です。
関数に成功コード(bool
)を返し、文字列への参照を渡して、見つかった場合に実際に値を返すようにします。例えば、
_bool get_tag_value(const string& tag, string& value)
{
auto t = my_map.find(tag);
if (t == my_map.end()) return false;
value = t->second;
return true;
}
_
キーが見つからない場合はunordered_map::at()
がスローされますが、unordered_map::find()
は無効なイテレータ(unordered_map::end()
)を返すため、この方法で例外を処理することを回避できます。
文字列を返すことに固執したい場合は、キーが見つからない場合は単に空の文字列(return string();
)を返します。
これらは、ブーストを使用する意欲に応じて検討する2つのオプションです。
ポインタを返します:
/* const? */ string* get_tag_value_ptr(const string& tag)
{
auto it = theMap.find(tag);
if (it != theMap.end()) {
return &it->second;
}
return nullptr;
}
オプションの参照を返します:
boost::optional</* const? */ string&> get_tag_value_opt(const string& tag)
{
auto it = theMap.find(tag);
if (it != theMap.end()) {
return it->second;
}
return boost::none;
}
うまくいけば、std::optional
まもなく、C++ 14から延期されましたが。
これらの取得方法では、マップから値をコピーする必要はありません。 outパラメータを介して返すことは、値のコピーを作成することを意味します。私はそれがあなたの要件が何であるかに依存すると思います。