Первый вопрос: можно ли «заставить» const_iterator
используя авто?
Например:
map<int> usa;
//...init usa
auto city_it = usa.find("New York");
Я просто хочу запросить вместо того, чтобы изменить что-либо, указанное city_it
так что я хотел бы иметь city_it
быть map<int>::const_iterator
, Но с помощью авто, city_it
совпадает с типом возврата map::find()
, который map<int>::iterator
, Любое предложение?
Извините, но я просто думаю, что лучшее предложение не с помощью auto
вообще, так как вы хотите выполнить (неявно действительный) преобразование типов. 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");
Это не совсем другой взгляд на преобразование в const
по сравнению с ответом @ Jollymorphic, но я думаю, что иметь такую полезную однострочную функцию удобно:
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_
Возможны альтернативы.
Еще один вариант, использующий auto (сохраняющий как изменчивые США, так и постоянные США):
map<std::string, int> usa;
//...init usa
const auto &const_usa = usa;
auto city_it = const_usa.find("New York");
Если вам не нужно, чтобы карта была изменчивой после init, есть несколько других вариантов.
Вы можете определить usa как const и инициировать его с помощью вызова функции:
const map<std::string, int> usa = init_usa();
auto city_it = usa.find("New York");
или используя лямбду для инициализации карты констант:
const auto usa = [&]()->const map<std::string, int>
{
map<std::string, int> usa;
//...init usa
return usa;
}();
auto city_it = usa.find("New York");
Чистым решением является работа с Const ссылка на карту, которую можно изменить:
const auto &const_usa = usa;
auto city_it = const_usa.find("New York");
Это убедится, что вы не можете изменить const_usa
и будет использовать константные итераторы.
Начиная с C ++ 17 вы можете использовать std::as_const
как это:
#include <utility>
// ...
auto city_it = std::as_const(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");
Вы можете использовать авто, чтобы «отслеживать» тип или «выводить» тип:
// deduce
auto city_it = usa.find("New York");
// track
auto city_it = std::map<int>::const_iterator( usa.find("New York"));
Кроме того, часы — это современные разговоры в стиле c ++ Херба Саттера, которые охватывают большую часть руководства по выводам этих типов.
https://youtu.be/xnqTKD8uD64