Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Парный итератор 
V
    Опции темы
borisbn
Дата 12.11.2011, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Всем привет. Название не очень, но попробую объяснить здесь.
Не так часто, но, в общем-то, и не редко, бывают ситуации, когда необходимо пройтись сразу по двум контейнерам. Естественно, предполагается, что они одинакового размера. Есть парочка вариантов, как это сделать:
1) В цикле for инициализировать два итератора и инкрементировать оба (так себе объяснение... лучше код)
Код

container_1_t c1;
container_2_t c2;
...
container_1_t::iterator it1 = c1.begin();
container_2_t::iterator it2 = c2.begin();
for (; it1 != c1.end(); ++it1, ++it2 ) {
  cout << (*it1) cout << (*it2);
}

2) Создать структуру из двух элементов, слить в один контейнер данные из обоих контейнеров:
Код

struct Common {
   T1 t1;
   T2 t2;
}
common_container_t< Common > common;
// слить
for ( common_container_t::iterator it = common.begin(); it != common.end(); ++it ) {
    cout << it->t1 << it->t2;
}


оба способа мне не нравятся: первый способ - просто не нравится smile , а для второго нужно делать много лишних (с точки зрения логики программы) действий.

Почитывая описание BOOST_FOREACH наткнулся на такую фразу
Цитата

For example, we can use BOOST_FOREACH with: 
  STL containers 
  arrays 
  Null-terminated strings (char and wchar_t) 
  std::pair of iterators


и вот последний пункт меня заинтересовал.

Теперь, собственно, вопрос: можно ли как-то стандартным способом пройтись по двум контейнерам ?
Типа такого:
Код

container_1_t c1;
container_2_t c2;
boost::iterator_pair< container_1_t::iterator, container_2_t::iterator > iterators( c1, c2 );
for_each( iterators.begin(), iterators.end(), foo() );
...
foo( std::pair< T1, T2 > pair ) {
    cout <<  pair.first < pair.second;
}


Спасибо.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
alexvs11
Дата 12.11.2011, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 6
Всего: 10



Код

#include <iostream>
#include <algorithm>
#include <list>

bool mypredicate (int i, int j) {
  std::cout << i << '*' << j << '=' << i * j << std::endl;
  return true;
}

int main () {
  std::vector<int> v1;
  std::list<int> v2;
  for (int i=0;i<10;++i)
  { 
     v1.push_back(i);
     v2.push_back(i*2);
  }
  
  std::mismatch(v1.begin(), v1.end(), v2.begin(), mypredicate);

  return 0;
}


наверно есть более подходящий алгоритм smile 

Это сообщение отредактировал(а) alexvs11 - 12.11.2011, 18:19
PM MAIL   Вверх
bsa
Дата 12.11.2011, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(borisbn @  12.11.2011,  19:03 Найти цитируемый пост)
Теперь, собственно, вопрос: можно ли как-то стандартным способом пройтись по двум контейнерам ?

std::transform.
PM   Вверх
alexvs11
Дата 12.11.2011, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 6
Всего: 10



bsa, да, но там есть ненужны OutputIterator
PM MAIL   Вверх
bsa
Дата 12.11.2011, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(alexvs11 @  12.11.2011,  20:14 Найти цитируемый пост)
bsa, да, но там есть ненужны OutputIterator 

никто не мешает сделать "пустой" OutputIterator
PM   Вверх
borisbn
Дата 12.11.2011, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



bsa, ага. на transform заглядывался, но мне не понравилось, что нужно делать предикат (нельзя просто for), да и свой "пустой" iterator тоже лениво делать smile Ничего сложного - просто лениво.
А что, всё-таки, значит строка в доке к бусту:
Цитата
we can use BOOST_FOREACH with std::pair of iterators

Не то, что мне нужно ?

Это сообщение отредактировал(а) borisbn - 12.11.2011, 19:45


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
alexvs11
Дата 12.11.2011, 19:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 6
Всего: 10



borisbn, а mismatch?
насчет предиката - этож stl, как иначе

по-поводу BOOST_FOREACH походу это только для std::map
PM MAIL   Вверх
boostcoder
Дата 12.11.2011, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(borisbn @  12.11.2011,  19:44 Найти цитируемый пост)
А что, всё-таки, значит строка в доке к бусту

это поддержка спецификации boost.range, ибо там один объект хранит два итератора, т.е. range.
Код

#include <iostream>
#include <string>
#include <utility>
#include <boost/foreach.hpp>

int main() {
   std::string s1("123456");
   
   BOOST_FOREACH(char ch, std::make_pair(s1.begin(), s1.end())) {
      std::cout << ch;
   }
}

http://liveworkspace.org/code/51c356368117...509eec8fff40ac4

Добавлено через 1 минуту и 46 секунд
Цитата(alexvs11 @  12.11.2011,  19:56 Найти цитируемый пост)
BOOST_FOREACH походу это только для std::map

приведи пример пожалуйста.
PM WWW   Вверх
alexvs11
Дата 12.11.2011, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


hell is here
**


Профиль
Группа: Участник
Сообщений: 518
Регистрация: 21.8.2010

Репутация: 6
Всего: 10



Цитата(boostcoder @  12.11.2011,  20:04 Найти цитируемый пост)
приведи пример пожалуйста. 

вы видимо ответили на вопрос
я чисто по отрывкам из интернетов сделал вывод
PM MAIL   Вверх
boostcoder
Дата 12.11.2011, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



borisbn, а вот ответ на твой вопрос:
Код

#include <iostream>
#include <string>
#include <boost/range/algorithm_ext/for_each.hpp>

int main() {
   std::string s1("123456");
   std::string s2(s1);
   
   boost::for_each(s1, s2,
      [](char c1, char c2) {
         std::cout << "c1: " << c1 << std::endl;
         std::cout << "c2: " << c2 << std::endl;
      }
   );
}

http://liveworkspace.org/code/0d3632e0846e...482af54dbc28e52
PM WWW   Вверх
borisbn
Дата 12.11.2011, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(boostcoder @  12.11.2011,  20:04 Найти цитируемый пост)
BOOST_FOREACH(char ch, std::make_pair(s1.begin(), s1.end()))

ясно. не то.

Цитата(boostcoder @  12.11.2011,  20:26 Найти цитируемый пост)
boost::for_each(s1, s2,

то. типа "sugar" version of transform...
ИМХО пример был бы лучше такой (разные контейнеры)
Код

   std::vector< int > s1 = { 1, 2, 3, 4, 5 };
   std::vector< std::string > s2 = { "qwe", "rty", "asd", "fgh", "zxc" };
   
   boost::for_each(s1, s2,
      []( int c1, const std::string & c2 ) {
         std::cout << "c1: " << c1 << std::endl;
         std::cout << "c2: " << c2 << std::endl;
      }
   );


boostcoder, респект и спасибо.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0815 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.