Как выбрать тип итератора с помощью автоматической переменной?

У меня есть std::unordered_map

std::unordered_map<std::string, std::string> myMap;

Я хочу получить итератор const, используя find. В С++ 03 я бы сделал

std::unordered_map<std::string, std::string>::const_iterator = myMap.find("SomeValue");

В С++ 11 я бы хотел использовать auto, чтобы сократить количество шаблонов.

auto = myMap.find("SomeValue");

Это будет const_iterator или iterator? Как компилятор решает, что использовать? Есть ли способ заставить его выбрать const?


person Jim Jeffries    schedule 26.02.2012    source источник
comment
Возможно, компилятор делает вывод типа для всей функции... Но почему константность итератора имеет для вас значение?   -  person Basile Starynkevitch    schedule 26.02.2012
comment
Если мое понимание перегрузки неверно (или en.cppreference.com/w/cpp /container/unordered_map/find неверно), nonConstMap.find всегда возвращает iterator. Тип возвращаемого значения и то, что вы делаете с результатом (например, передаете его конструктору const_iterator), не влияет на выбор перегрузки. То есть он возвращает const_iterator только в том случае, если вы вызываете constMap.find.   -  person    schedule 26.02.2012


Ответы (1)


Он будет использовать неконстантные итераторы, если myMap является неконстантным выражением. Поэтому вы могли бы сказать

#include <type_traits>
#include <utility>

template<typename T, typename Vc> struct apply_vc;
template<typename T, typename U> struct apply_vc<T, U&> {
  typedef T &type;
};
template<typename T, typename U> struct apply_vc<T, U&&> {
  typedef T &&type;
};

template<typename T> 
typename apply_vc<typename std::remove_reference<T>::type const, T&&>::type
const_(T &&t) {
  return std::forward<T>(t);
}

А потом

auto it = const_(myMap).find("SomeValue");
person Johannes Schaub - litb    schedule 26.02.2012
comment
Почему бы не просто template<typename T> const T& const_(T& t) { return t; } ? - person MSalters; 27.02.2012
comment
Это не будет работать с неконстантными значениями и преобразует константные значения в lvalue. нехорошо. - person Johannes Schaub - litb; 27.02.2012
comment
Я не рассматривал последнее (зачем делать что-то const, которое уже является const?), но вы все равно тривиально решили это с помощью перегрузки. Случай rvalue хорош, но я все еще пытаюсь понять apply_vc. Я вижу, что он делает, но не вижу, почему это необходимо. - person MSalters; 27.02.2012
comment
Он сохраняет rvalue как rvalue и lvalue как lvalue, так что перегрузка квалификатора ref для функций-членов все еще работает. - person Johannes Schaub - litb; 27.02.2012
comment
C++17 добавил std::as_const в заголовок ‹utility› ссылка - person ChetS; 20.08.2016