Цикл for на основе диапазона с boost :: adapter :: indexed

Цикл for на основе диапазона C ++ 11 разыменовывает итератор. Значит ли это, что нет смысла использовать его с boost::adaptors::indexed? Пример:

boost::counting_range numbers(10,20);
for(auto i : numbers | indexed(0)) {
  cout << "number = " i 
  /* << " | index = " << i.index() */ // i is an integer!
  << "\n";
}

Я всегда могу использовать счетчик, но мне нравятся индексированные итераторы.

  • Можно ли как-то использовать их с циклами for на основе диапазона?
  • Что такое идиома для использования циклов на основе диапазона с индексом? (просто счетчик?)

person gnzlbg    schedule 17.05.2013    source источник
comment
indexed отстой, потому что он добавляет метод index() к итератору, а не значение, возвращаемое при разыменовании итератора. : /   -  person Xeo    schedule 17.05.2013
comment
@Xeo Действительно. Время от времени мне нужен индекс элемента в диапазоне. Сначала я чувствую себя плохо из-за этого. Затем я ввожу счетчик. Если к контейнеру можно легко получить доступ с помощью простого старого цикла, я снова чувствую себя плохо и переписываю цикл на основе диапазона в простой старый цикл.   -  person gnzlbg    schedule 17.05.2013
comment
поскольку Xeo упомянул, что индексирование ускорения не подходит для этого. Если вы не против переключения библиотек, есть несколько библиотек диапазонов C ++ на основе itertools Python, например: github.com/ryanhaining / cppitertools   -  person Cechner    schedule 03.07.2014
comment
Примечание: это исправлено, начиная с Boost 1.56 (выпущено в августе 2014 г.); элемент косвенно указывается за value_type функциями-членами index() и value().   -  person ecatmur    schedule 21.01.2016
comment
@gnzlbg, вы можете исправить boost::adaptor::indexed на boost::adaptors::indexed, поскольку мне потребовалось время, чтобы понять, что s пропал?   -  person Enlico    schedule 18.11.2019
comment
@EnricoMariaDeAngelis готово!   -  person gnzlbg    schedule 19.11.2019


Ответы (2)


Это было исправлено в Boost 1.56 (выпущен в августе 2014 г.); элемент косвенно указывается за value_type функциями-членами index() и value().

Пример: http://coliru.stacked-crooked.com/a/e95bdff0a9d371ea

auto numbers = boost::counting_range(10, 20);
for (auto i : numbers | boost::adaptors::indexed())
    std::cout << "number = " << i.value()
        << " | index = " << i.index() << "\n";
person ecatmur    schedule 21.01.2016

Короткий ответ (как и все в комментариях) - «правильно, это не имеет смысла». Меня это тоже раздражает. В зависимости от вашего стиля программирования вам может понравиться написанный мной пакет "zipfor" (только заголовок): из github

Это позволяет синтаксис вроде

std::vector v;
zipfor(x,i eachin v, icounter) {
   // use x as deferenced element of x
   // and i as index
}

К сожалению, я не могу придумать способ использования синтаксиса на основе дальности и вынужден прибегать к макросу "zipfor" :(

Заголовок изначально был разработан для таких вещей, как

std::vector v,w;
zipfor(x,y eachin v,w) {
   // x is element of v
   // y is element of w (both iterated in parallel)
}

и

std::map m;
mapfor(k,v eachin m)
   // k is key and v is value of pair in m

Мои тесты на g ++ 4.8 с полной оптимизацией показывают, что полученный код работает не медленнее, чем писать его вручную.

person cshelton    schedule 25.08.2014