2013-05-17 2 views
6

В основе C++ 11 для циклов лежит разделение на итератор. Означает ли это, что нет смысла использовать его с boost::adaptor::indexed? Пример:Диапазон для цикла с boost :: adapter :: indexed

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

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

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

'indexed' сосет, потому что это добавляет' индекс() 'методы к * * итератору, а не значение, возвращаемое из разыменования итератора. :/ – Xeo

+1

@Xeo Действительно. Время от времени мне нужен индекс элемента в диапазоне. Сначала я плохо себя чувствую. Затем я вводил счетчик. Если к контейнеру можно легко получить доступ с простой старой петлей, я снова чувствую себя плохо и переписываю петлю на основе диапазона в простой старый цикл. – gnzlbg

+2

, так как Xeo упомянутый boost indexed не подходит для этого. Если вы не возражаете против коммутирующих библиотек, то есть несколько библиотек диапазонов C++ на основе itertools python, таких как: https://github.com/ryanhaining/cppitertools/ – Cechner

ответ

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"; 
0

Короткий ответ (как отмечают все упомянутые комментарии) «прав, это не имеет смысла». Я также нашел это раздражающим. В зависимости от вашего стиля программирования, вы можете нравится «zipfor» пакет, который я написал (только заголовок): from 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 с полной оптимизацией показывают, что полученный код не медленнее, чем записывать его вручную.

Смежные вопросы