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

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

Страниц: 1 [2] 3 4 5   Вниз
  Печать  
Автор Тема: QList::insert (multi)  (Прочитано 28229 раз)
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #15 : Октябрь 03, 2018, 13:20 »

А по теме:
С удивлением обнаружил что QList умеет вставлять только "по одному" - пришлось использовать вектор указателей. Не беда, но все-таки.. Или я плохо читал букварь?  Плиз "ткните носиком"

В контейнерах особо и не должно быть кучи методов на все случаи жизни. Если таким желаниям потакать, то найдётся много желающих туда свои хотелки запихнуть. И тогда в другие контейнеры придётся добавлять такой же функционал. Поэтому: контейнеры отдельно, алгоритмы отдельно. То, что Вы хотите сделать, больше подходит под алгоритм. Так что или готовый подбирайте, или свой пишите.
Записан

Пока сам не сделаешь...
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #16 : Октябрь 03, 2018, 14:45 »

Сколько аллокаций в последней строке?
Для QString сработает как вектор (sizeof(QString) == sizeof(void *)), поэтому вероятно ни одной (пул). Размер QImage навскидку не помню, наверное > sizeof(void *) (если не так поправьте), поэтому кроме вставки в массив указателей будет еще и выделение блока для эл-та QImage - хотя это и не оптимально. Да, возможно для хранения QImage(й) оптимальнее QVector, особенно с учетом implicit шары. И что? Не вижу никаких оснований для "снисходительной иронии"  Улыбающийся (на базе сомнительной статьи).

Всё верно. Вас устраивает контейнер, который для одних _кутешных_ типов эффективен, а для других - нет? И без знания что "у ей внутре" не скажешь, подойдет лист, или нет.
К примеру, QVariant - плохой тип для листа, хотя есть QVariantList и он много где используется.
К 6ке вроде бы закопают qlist. Ну я на это надеюсь.

Вообще, std::deque лучше примерно всем.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #17 : Октябрь 03, 2018, 14:46 »

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

Ну удачи написать внешний range-insert))))
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #18 : Октябрь 03, 2018, 14:48 »

. Мне вот идея QList кажется весьма разумной, многие ситуации он покрывает, пусть не все.

Аллоцировать на каждую вставку чтобы сэкономить немного бинарного кода в QtCore? Отличная идея!
« Последнее редактирование: Октябрь 03, 2018, 22:15 от Авварон » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #19 : Октябрь 03, 2018, 16:14 »

Вас устраивает контейнер, который для одних _кутешных_ типов эффективен, а для других - нет? И без знания что "у ей внутре" не скажешь, подойдет лист, или нет.
В принципе - да, устраивает, хотя (за европейскую зарплату) мог быть и лучше. И да, любой контейнер эффективен для одних типов, но не для всех. И знать потроха (хотя бы в общих чертах) обов'язково.

Вообще, std::deque лучше примерно всем.
К сожалению, MSVC реализация ставит на нем крест Плачущий Да и в других размера чанка не хватает, поэтому давно использую самописную деку. Насчет "всем" это Вы конечно загнули, он силен только на push_back, но во многих задачах это важно.

В контейнерах особо и не должно быть кучи методов на все случаи жизни. Если таким желаниям потакать, то найдётся много желающих туда свои хотелки запихнуть. И тогда в другие контейнеры придётся добавлять такой же функционал. Поэтому: контейнеры отдельно, алгоритмы отдельно. То, что Вы хотите сделать, больше подходит под алгоритм. Так что или готовый подбирайте, или свой пишите.
Мда, сегодня наверное "не Ваш день", сделаю вид что не слышал  Улыбающийся
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #20 : Октябрь 03, 2018, 16:18 »

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

Ну удачи написать внешний range-insert))))

Я говорил в общем о подходе. Определяется необходимый и достаточный набор методов для контейнеров (в STL описываются в Named requirements), остальное выносится в алгоритмы.

Имея метод
Код
C++ (Qt)
QList::iterator QList::insert(QList::iterator before, const T &value)
нужно какую-то rocket science применить, чтобы внешний range-insert написать? Улыбающийся Эффективность такого решения - отдельный разговор.
Записан

Пока сам не сделаешь...
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #21 : Октябрь 03, 2018, 16:27 »

В контейнерах особо и не должно быть кучи методов на все случаи жизни. Если таким желаниям потакать, то найдётся много желающих туда свои хотелки запихнуть. И тогда в другие контейнеры придётся добавлять такой же функционал. Поэтому: контейнеры отдельно, алгоритмы отдельно. То, что Вы хотите сделать, больше подходит под алгоритм. Так что или готовый подбирайте, или свой пишите.
Мда, сегодня наверное "не Ваш день", сделаю вид что не слышал  Улыбающийся

А что не так? Сделайте мой день Улыбающийся.
Записан

Пока сам не сделаешь...
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #22 : Октябрь 03, 2018, 22:18 »

нужно какую-то rocket science применить, чтобы внешний range-insert написать? Улыбающийся Эффективность такого решения - отдельный разговор.

Смысл member range-insert у вектора - одна аллокация и один сдвиг хвоста вектора.
Без доступа к методам reserve(), end() ничего не выйдет.
Так что удачи с генерик алгоритмом.
« Последнее редактирование: Октябрь 03, 2018, 22:21 от Авварон » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #23 : Октябрь 03, 2018, 22:21 »

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

К сожалению, MSVC реализация ставит на нем крест Плачущий Да и в других размера чанка не хватает, поэтому давно использую самописную деку. Насчет "всем" это Вы конечно загнули, он силен только на push_back, но во многих задачах это важно.
Интересно, не знал. А в новой студии не поправили?
А как же insert, он тоже быстрее становится - достаточно подвинуть чанк а не весь хвост.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #24 : Октябрь 04, 2018, 00:40 »

Смысл member range-insert у вектора - одна аллокация и один сдвиг хвоста вектора.
Без доступа к методам reserve(), end() ничего не выйдет.
Так что удачи с генерик алгоритмом.

Прям совсем ничего не выйдет? Улыбающийся Или не выйдет оптимально(по каким-то критериям)? И при чём тут конкретно вектор(я так понимаю std::vector имеется в виду)? Других контейнеров, куда можно вставлять в заданную позицию, не существует?
Записан

Пока сам не сделаешь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #25 : Октябрь 04, 2018, 06:40 »

А в новой студии не поправили?
Не знаю, но если так зависеть от реализации - зачем тогда std?
А как же insert, он тоже быстрее становится - достаточно подвинуть чанк а не весь хвост.
Так не выходит, эл-ты во всех последующих чанках тоже надо месить. Дека очень важна когда счет идет на мульены, тогда пере-распределение "всего" (вектор) просто вешает ОС.

А еще хороший малоизвестный контейнер sequence (?) насколько помню так он называется в std. Доступа по индексу нет, просто можно создавать новый эл-т (обычно для хранения его указателя в др контейнере) и "удалять" (мнимо). Типа кастомной кучи/аллокатора.

Смысл member range-insert у вектора - одна аллокация и один сдвиг хвоста вектора.
Без доступа к методам reserve(), end() ничего не выйдет.
Так что удачи с генерик алгоритмом.

Прям совсем ничего не выйдет? Улыбающийся Или не выйдет оптимально(по каким-то критериям)? И при чём тут конкретно вектор(я так понимаю std::vector имеется в виду)? Других контейнеров, куда можно вставлять в заданную позицию, не существует?
Все Вам правильно объяснили, чего тормозите? Сделать множ вставку в QList я не могу т.к. доступ к массиву указателей наглухо перекрыт (из идейных соображений). Да и вообще, чего это, взяв готовый/штатный контейнер, я должен его "доделывать"? У др контейнеров с доступом по индексу этот ф-ционал всю жизнь был. Ну а о том что вставка/удаление для таких контейнеров - удовольствие дорогое, и оптимизировать их программист просто обязан - и напоминать неудобно.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #26 : Октябрь 04, 2018, 12:13 »

Understand the Qt containers.
Статья уже старая, но для общего понимания довольно-таки неплоха.
Записан

Qt 5.11/4.8.7 (X11/Win)
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #27 : Октябрь 04, 2018, 13:30 »

Все Вам правильно объяснили, чего тормозите?

Отсылки к частной реализации частной операции в частном контейнере и постоянные пожелания удачи как-то слабо тянут на "правильное объяснение". То, что из множественных вставок по одному элементу в контейнер, который для этого плохо подходит, ничего хорошего не получится - это и ежу понятно. Но это не значит, что так делать в принципе нельзя и "ничего не выйдет". Про эффективность я сразу отметил.

Сделать множ вставку в QList я не могу т.к. доступ к массиву указателей наглухо перекрыт (из идейных соображений). Да и вообще, чего это, взяв готовый/штатный контейнер, я должен его "доделывать"?  У др контейнеров с доступом по индексу этот ф-ционал всю жизнь был.

Вы, похоже, много всего не можете сделать Улыбающийся. Но это, опять же, не означает, что это в принципе невозможно сделать. Почему не пользуетесь теми другими хорошими контейнерами, зачем Вам плохой QList? Если вернуться к баранам и говорить конкретно о QList, то можно предложить такие варианты:

1. Написать в Qt feature request на добавление нужных методов insert.
2. Самому пропатчить Qt и добавить нужные Вам методы insert.
3. Написать функцию, которая в QList вставляет несколько элементов по одному.
4. Воспользоваться готовым алгоритмом из STL:
Код
C++ (Qt)
#include <QList>
#include <QDebug>
#include <iterator>
 
int main()
{
   QList<int> a = {1, 2, 7};
   QList<int> b = {1, 2, 3, 4, 5, 6, 7};
 
   std::copy(b.begin() + 2, b.end() - 1, std::inserter(a, a.begin() + 2));
 
   qDebug() << a;
}

Да, стандартные алгоритмы работают даже с ущербными кутешными контейнерами, если в них есть необходимый базовый функционал.

Ну а о том что вставка/удаление для таких контейнеров - удовольствие дорогое, и оптимизировать их программист просто обязан - и напоминать неудобно.

Ещё неудобно напоминать, что для конкретной задачи нужно подбирать контейнер, который для неё подходит оптимальным образом. Вы, похоже, методом тыка выбираете: есть ли в контейнере нужные методы или нет, а не исходя из его характеристик и назначения. Ну и для каких задач предназначен контейнер, мы опять скорей всего не узнаем. Может нужно делать миллион вставок по десятку элементов в разные места контейнера? Расскажите ещё раз, что если Вы не указали что-то, то нужно подразумевать то-то, если не отметили другое, то это обозначает третье. Очень интересно послушать Улыбающийся.
Записан

Пока сам не сделаешь...
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #28 : Октябрь 04, 2018, 16:38 »


Отсылки к частной реализации частной операции в частном контейнере и постоянные пожелания удачи как-то слабо тянут на "правильное объяснение". То, что из множественных вставок по одному элементу в контейнер, который для этого плохо подходит, ничего хорошего не получится - это и ежу понятно. Но это не значит, что так делать в принципе нельзя и "ничего не выйдет". Про эффективность я сразу отметил.

Эта частная операция в частном (vector, deque) контейнере позволяет снизить сложность алгоритма вставки в середину с O(M*N) до О(N). Утверждать что такая оптимизация не нужна for the sake of algorithms не оч умно так-то.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #29 : Октябрь 04, 2018, 16:40 »


1. Написать в Qt feature request на добавление нужных методов insert.
Won't fix.

2. Самому пропатчить Qt и добавить нужные Вам методы insert.
Поставят -1.
Записан
Страниц: 1 [2] 3 4 5   Вверх
  Печать  
 
Перейти в:  


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