すべてのC++ライブラリの決定と同様に、この根本には哲学的な疑問があります。
vector
では、operator[]
がconstとnon-constの両方の場合について定義されています。長さNのベクトルの場合、operator[](0...N-1)
はとなるので、constであろうとなかろうと、常にの意味を持つからです。要素が存在します。
これをベースラインとして、地図はどうすればよいですか?下付き文字(キー)がまったく存在するかどうかを判断する絶対的な基準はありません。
可変要素operator[]
を使用すると、要素のデフォルト構成を選択することは妥当です。すべての呼び出し元がそれを参照した後、彼はそれが存在することを期待しており、存在できると考えます。これは、少なくとも驚きのパスです。
不変の場合はどうなりますか?要素は存在していても存在しなくてもよく、存在しない場合は、const
の精神に違反するので、マップを変更することはできません。
vector
を扱うことに慣れていた人にとっては、例外が発生する可能性があるため、例外をスローする必要はありません。次に、非常に異なる動作を持つ2つの同様の外観のインターフェースがあります。
答えは、可変演算子[]をまったく提供しないことです。開発者は(あなたのように)それが存在しないことに気付くかもしれませんが、ドキュメントを見て間違ったツリーを吠えていることに気づく機会があります。
前述したように、at()
(ベクトルのように添字が存在しない場合は例外をスローします)とfind()
があります。
私たちは自分自身の効用関数を与えることができますブーストから(そしてすぐに、++ 17 C)少しの助けを借りて
:
#include <map>
#include <string>
#include <utility>
#include <type_traits>
#include <iostream>
#include <boost/optional.hpp>
template<class Map>
auto maybe_get_impl(Map& map, typename Map::key_type const& key)
{
using reference_type = std::conditional_t<
std::is_const<std::remove_reference_t<Map>>::value,
typename Map::mapped_type const&,
typename Map::mapped_type&>;
boost::optional<reference_type> result;
auto ifind = map.find(key);
if (ifind != map.end())
{
result = ifind->second;
}
return result;
}
template<class K, class V, class Comp, class A>
auto maybe_get(std::map<K, V, Comp, A> const& map, K const& key)
{
return maybe_get_impl(map, key);
}
template<class K, class V, class Comp, class A>
auto maybe_get(std::map<K, V, Comp, A>& map, K const& key)
{
return maybe_get_impl(map, key);
}
int main()
{
std::map<int, std::string> mymap;
mymap.emplace(1, "hello");
mymap.emplace(2, "world");
// note: non-const because we're taking a reference from a mutable map;
std::string part = std::string("goodbye, cruel world");
std::cout << maybe_get(mymap, 1).value_or(part) << std::endl;
std::cout << maybe_get(mymap, 2).value_or(part) << std::endl;
std::cout << maybe_get(mymap, 0).value_or(part) << std::endl;
}
予想される出力:
hello
world
goodbye, cruel world
あなたは( 'cbeginを試してみました) '? –
_理由は、演算子[]がconstでないためですか? "はい、[ここ](http://en.cppreference.com/w/cpp/container/map/operator_at)を参照してください。 –