最初の質問:autoを使用して_const_iterator
_を「強制」することは可能ですか?例えば:
_map<int> usa;
//...init usa
auto city_it = usa.find("New York");
_
_city_it
_が指すものを変更するのではなく、単に照会したいので、_city_it
_を_map<int>::const_iterator
_にしたいです。ただし、autoを使用すると、_city_it
_はmap::find()
の戻り値の型である_map<int>::iterator
_と同じになります。なにか提案を?
申し訳ありませんが、(暗黙的に有効な)型変換を実行するため、auto
を使用してnotとすることをお勧めします。 auto
は、正確なタイプを推定するためのもので、ここでは望んでいません。
次のように書いてください:
std::map<std::string, int>::const_iterator city_it = usa.find("New York");
MooingDuckが正しく指摘したように、型エイリアスを使用すると、コードの可読性と保守性が向上します。
typedef std::map<std::string, int> my_map;
my_map::const_iterator city_it = usa.find("New York");
これは、@ Jollymorphicの答えと比較したconst
への変換に関する劇的な違いはありませんが、このようなユーティリティワンライナー関数を使用すると便利だと思います。
template<class T> T const& constant(T& v){ return v; }
これにより、変換が目に魅力的になります。
auto it = constant(usa).find("New York");
// other solutions for direct lengths comparision
std::map<std::string, int>::const_iterator city_it = usa.find("New York");
auto city_it = const_cast<const std::map<std::string, int>&>(usa).find("New York");
まあ、私は言うが、大きいほど良いとは限りません。もちろん、好みに応じて関数の名前を選択できます-as_const
あるいは単に const_
は可能な選択肢です。
C++ 17以降では、 std::as_const
このように:
#include <utility>
// ...
auto city_it = std::as_const(usa).find("New York");
きれいな解決策は、そうでなければ変更可能なマップへのconst参照を使用することです。
const auto &const_usa = usa;
auto city_it = const_usa.find("New York");
これにより、変更できなくなりますconst_usa
、およびconstイテレータを使用します。
Autoを使用した別のバリエーション(変更可能なusaとconst usaの両方を保持する):
map<std::string, int> usa;
//...init usa
const auto &const_usa = usa;
auto city_it = const_usa.find("New York");
初期化後にマップをまったく変更する必要がない場合は、他のオプションがいくつかあります。
usaをconstとして定義し、関数呼び出しで初期化できます。
const map<std::string, int> usa = init_usa();
auto city_it = usa.find("New York");
または、ラムダを使用してconstマップを初期化します。
const auto usa = [&]()->const map<std::string, int>
{
map<std::string, int> usa;
//...init usa
return usa;
}();
auto city_it = usa.find("New York");
私は今これをテストする立場にありませんが、トリックを行うと思います:
auto city_it = const_cast< const map<int> & >(usa).find("New York");
C++ 11では、これを行うことができます。
decltype(usa)::const_iterator city_it = usa.find("New York");