web-dev-qa-db-ja.com

autoを使用してconst_iteratorを取得するにはどうすればよいですか?

最初の質問: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_と同じになります。なにか提案を?

51
virtualPN

申し訳ありませんが、(暗黙的に有効な)型変換を実行するため、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");
35
Andy Prowl

これは、@ 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_は可能な選択肢です。

12
Xeo

C++ 17以降では、 std::as_const このように:

#include <utility>

// ...

auto city_it = std::as_const(usa).find("New York");
8
jhasse

きれいな解決策は、そうでなければ変更可能なマップへのconst参照を使用することです。

const auto &const_usa = usa;
auto city_it = const_usa.find("New York");

これにより、変更できなくなりますconst_usa、およびconstイテレータを使用します。

7
rustyx

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");
6
ChetS

私は今これをテストする立場にありませんが、トリックを行うと思います:

auto city_it = const_cast< const map<int> & >(usa).find("New York");
1
Jollymorphic

C++ 11では、これを行うことができます。

decltype(usa)::const_iterator city_it = usa.find("New York");
0
snips-n-snails