Russian Qt Forum
Май 06, 2024, 22:26 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: выбор направления прохода по контейнеру  (Прочитано 12712 раз)
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« : Февраль 06, 2016, 16:59 »

Здравствуйте. Казалось бы, элементарная задача — бегать по контейнеру вперед или назад в зависимости от флага. Ну я сразу и написал (код упрощен):
Код
C++ (Qt)
void traverse(vector<int> v, bool reverse)
{
   auto it  = reverse ? v.crbegin() : v.cbegin();
   auto end = reverse ? v.crend()   : v.cend();
   while (it != end)
   {
       auto n = *it++;
       ...
   }
}
тут-то меня компилятор и обругал за разные типы прямого и обратного итераторов Грустный

сделал пока через std::reverse, но можно ли лучше?
Код
C++ (Qt)
void traverse(vector<int> v, bool reverse)
{
   auto vv = v;
   if (reverse)
       std::reverse(vv.cbegin(), vv.cend());
   for (auto n : vv)
   {
       ...
   }
}
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Февраль 06, 2016, 18:01 »

Понимаю что "код упрощен", но все же подача по значению, а потом еще одно копирование просто ужасно.
Я бы писал так
Код
C++ (Qt)
for (size_t i = 0; i < vec.size(); ++i) {
size_t index = reverse ? (vec.size() - i - 1) : i;
vec[index] = ...
}
 
А если нет доступа по индексу то так
Код
C++ (Qt)
auto itF = vec.begin();
auto itB = vec.rbegin();
 
whle (true) {
 if (!reverse && itF == vec.end()) break;
 if (reverse && itB == vec.rend()) break;
 auto & val = reverse ? (*itB++) : (*itF++);
 ...
}
 
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #2 : Февраль 06, 2016, 20:15 »

второй вариант как-то совсем не нравится.

по индексам норм. изначально не хотел с ними связываться т.к. они больше ни для чего не понадобятся.

спасибо.
но все же подача по значению, а потом еще одно копирование просто ужасно.
ну так это и есть упрощение Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #3 : Февраль 06, 2016, 21:01 »

Код
C++ (Qt)
template<typename Container, typename Func>
void func( Container c, Func func, bool reverse )
{
if( reverse )
for_each( c.crbegin(), c.crend(), func );
else
for_each( c.cbegin(), c.cend(), func );
}
 
int main( int, char *[] )
{
vector<int> data { 10, 20, 30, 40, 50 };
 
func( data, [=]( int v ){ cerr << v << endl; }, false );
 
return 0;
}
 
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #4 : Февраль 06, 2016, 22:59 »

Вот последний вариант, имхо, самый правильный.
Если бы еще не этот мерзкий синтаксис новых сей...
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #5 : Февраль 06, 2016, 23:03 »

Если бы еще не этот мерзкий синтаксис новых сей...
Вы про лябды? Так их не обяхательно использовать, можно обойтись функтором или обычной функцией.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #6 : Февраль 07, 2016, 00:50 »

спасибо, про for_each не подумал. но мне внутри надо вызывать другую лямбду, у которой параметром не только элемент контейнера, так что не очень подходит.

остановился на использовании индексов.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #7 : Февраль 07, 2016, 01:35 »

Если бы еще не этот мерзкий синтаксис новых сей...
Вы про лябды? Так их не обяхательно использовать, можно обойтись функтором или обычной функцией.

Да это понятно, что можно обойтись... Просто язык и так перегружен всяким мусором, и вместо того, чтобы его почистить и упорядочить, с каждым новым стандартом привносится еще больше. Промышленный язык должен быть лаконичным и однозначным, а вместо решения реальных проблем, утолщается талмуд стандарта (который все равно мало кто читает, кроме утопистов-теоретиков). Ну хоть auto добавили, и на этом спасибо Улыбающийся
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Февраль 07, 2016, 06:07 »

Ну хоть auto добавили, и на этом спасибо Улыбающийся
То палка о двух концах
Код
C++ (Qt)
   auto vv = v;
Не вижу типа - и это часто невыгодно/неудобно.

второй вариант как-то совсем не нравится.
Конечно он не идеален, но по меньшей мере показывает что можно обойтись парой-тройкой строк, и нырять в пучины какого-нибудь "value_type" совсем необязательно  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #9 : Февраль 07, 2016, 07:49 »

но мне внутри надо вызывать другую лямбду, у которой параметром не только элемент контейнера
Не вижу проблемы. Внутренней лямбде могут быть доступны все данные.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Февраль 07, 2016, 08:00 »

Вот последний вариант, имхо, самый правильный.
Если бы еще не этот мерзкий синтаксис новых сей...
Ну да, "к прогрессу (или моде) нужно быть поближе".

Хорошо, допустим такой код работает. Но вот набежали новые фичи/изменения, и в теле цикла понадобился break. Измените пожалуйста  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #11 : Февраль 07, 2016, 08:12 »

Хорошо, допустим такой код работает. Но вот набежали новые фичи/изменения, и в теле цикла понадобился break. Измените пожалуйста  Улыбающийся
Меняем for_each на  find_if, а из лямбды возвращаем true, когда нужно прервать цикл.
« Последнее редактирование: Февраль 07, 2016, 08:48 от Old » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #12 : Февраль 07, 2016, 13:43 »

Не вижу типа - и это часто невыгодно/неудобно.
мышкой на переменную навести Улыбающийся хотя креатор типы контейнеров че-то не хочет показывать
но мне внутри надо вызывать другую лямбду, у которой параметром не только элемент контейнера
Не вижу проблемы. Внутренней лямбде могут быть доступны все данные.
да, это понятно. но данные эти придется тащить через еще один уровень Улыбающийся
« Последнее редактирование: Февраль 07, 2016, 13:45 от kambala » Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Февраль 07, 2016, 13:52 »

да, это понятно. но данные эти придется тащить через еще один уровень Улыбающийся
Ну и что? Зато как грамотно написано! И лямбды (причем вложенные, а не так себе), и темплейты и std - всем владеем виртуозно  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #14 : Февраль 07, 2016, 14:50 »

Ну и что? Зато как грамотно написано! И лямбды (причем вложенные, а не так себе), и темплейты и std - всем владеем виртуозно  Улыбающийся

Да, такое конечно получше: Улыбающийся
Код
C++ (Qt)
auto itF = vec.begin();
auto itB = vec.rbegin();
 
whle (true) {
 if (!reverse && itF == vec.end()) break;
 if (reverse && itB == vec.rend()) break;
 auto & val = reverse ? (*itB++) : (*itF++);
 ...
}
 
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.167 секунд. Запросов: 23.