В С++ 11 реализован цикл, основанный на диапазоне, который внутренне реализуется с использованием (const) итераторов, поэтому это:
std::vector<std::string> vec;
for(std::string &str : vec)
{
//...
}
в основном эквивалентен более подробному (да, его можно упростить с помощью auto
):
for(std::vector<std::string>::iterator it = vec.begin(); it != vec.end(); ++it)
{
//...
}
Однако обычно требуется также индекс элемента. С помощью второго подхода легко:
auto index = it - vec.begin();
В режиме for
на основе диапазона это не так просто. Но Мне было интересно, было ли это нормально и портативное решение, которое вообще избегает итераторов:
for(auto &str : vec)
{
auto index = &str - &vec[0];
}
(const
версия будет такой же, но нужно следить за тем, чтобы не смешивать контейнер const
с константной ссылкой, которая может не всегда быть очевидной.)
Очевидно, это зависит от нескольких предположений:
-
что итератор вектора - это просто ссылка на элемент (возможно, в стандарте?)
-
контейнер гарантирован непрерывным (
std::vector
is...) -
внутренняя реализация диапазона, основанного на (также, вероятно, в стандарте)