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

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

Страниц: 1 [2] 3 4 5   Вниз
  Печать  
Автор Тема: SharedHash/Set  (Прочитано 49034 раз)
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #15 : Май 16, 2019, 14:31 »

Думается Вы напрасно уделяете std столько времени и сил - эта штука всегда была и будет "ширпотребом", чего-то с ней достичь невозможно. Игнорировать ее конечно не стоит, но так "упиваться" синтаксическим сахаром ни к чему. Ну это тоже больше для других  Улыбающийся

Сто раз обсуждали, но давайте еще:
1. QtContainers требуют T(), что заставляет делать null state у T (QString::isNull/isEmpty), что не для любого T имеет смысл.
2. QtContainers требуют T(const T&). Хотите положить unique_ptr в вектор? забудьте.
3. QtContainers не имеют emplace* методов. Если не юзать pimpl то append(T&&) может быть более затратным (каждый мембер же надо мувнуть). Впрочем, это мелочь.
4. QtContainers не имеют range_insert методов. Хотите быстро вставить в вектор, не двигая полвектора на каждый элемент? Пишите руками.
5. QtContainers любят детачить в рандомных местах, что заставляют писать boilerplate код с qAsConst/временными переменными. Поглядите как "умело" обращаются с ними сами кутешники: https://codereview.qt-project.org/#/c/253792/ Куча таких мест делала дип-копию контейнера. Ухху!
6. QtContainers медленее за счет лишнего разыменования d_ptr. Это в Qt6 пофиксят, правда.
7. QtContainers медленее за счет постоянной проверки refcount, даже когда идет append в цикле.
8. QtContainers генерят больше бинарного кода: https://codereview.qt-project.org/#/c/261870/
9. QMap/QHash нельзя итерировать в range-for по ключу-значению, что либо заставляет писать говнокод с итераторами, либо говнокод с .keys() и последующим .value(). Ухху!

Вам мало?

ЗЫ: до с++11 кутешные контейнеры вцелом имели паритет - что-то быстрее\удобнее, что-то медленее\неудобнее, но в целом пофиг было. Но с 11х плюсов 2 и 9 просто киллер фичи std. А в 17х даже не надо богомерзкую пару в range-for юзать, просто пишем for (auto&& [key, value]: map) {...}
« Последнее редактирование: Май 16, 2019, 14:47 от Авварон » Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #16 : Май 16, 2019, 14:33 »

Не видно явных, принципиальных плюсов (а их нет) - нечего тратить время на изучение "чуть лучшего".

Ну да, чтоб std::shared_ptr изучить, нужно потратить "неделю, не меньше!" Улыбающийся. Зато костыли для QHash пишутся легко и непринуждённо Улыбающийся. Кстати, какова сейчас политика партии: шаблоны - это хорошо или плохо?

Важно другое, но оно Вас не интересует - понимаю, поглощены изучением std...

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

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

Сообщений: 11445


Просмотр профиля
« Ответ #17 : Май 16, 2019, 16:18 »

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

Вот есть тот же QSharedPointer, он меня вполне устраивает, так какого <> без толку суетиться и менять его нв std? Впрочем обратное столь же верно.

Кстати пункт 4 не вполне точен: в QVector есть, а вот в QList нету.

Код
C++ (Qt)
9. QMap/QHash нельзя итерировать в range-for по ключу-значению, что либо заставляет писать говнокод с итераторами, либо говнокод с .keys() и последующим .value(). Ухху!
 
Здесь не понял проблему, расскажите подробнее. Спасибо

Вообще увлечение "общими" вещами на мой взгляд бесперспективно. Вы как бы оказываетесь в огромной толпе таких же (ну или говорящих что тоже знают Улыбающийся) - и это невыгодно.

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

Сообщений: 3258


Просмотр профиля
« Ответ #18 : Май 16, 2019, 16:33 »

Кстати пункт 4 не вполне точен: в QVector есть, а вот в QList нету.

Хде, покажите: https://doc.qt.io/qt-5/qvector.html#insert
Если что, range-insert это метод, принимающий 3 итератора: https://en.cppreference.com/w/cpp/container/vector/insert (4й оверлоад)

Здесь не понял проблему, расскажите подробнее. Спасибо

Код:
// c++17
std::map<QString, QVariant> map;
for (auto&& [key, value]: map) {
    qDebug() << "key:" << key << "value:" << value;
}

// qt good
QMap<QString, QVariant> map;
for (auto it = map.constBegin(), end = map.constEnd(); it != end; ++it) {
    qDebug() << "key:" << it.key() << "value:" << it.value();
}

// qt bad
QMap<QString, QVariant> map;
for (auto&& key: map.keys()) { // ой, аллокация и куча ref/deref строк
    qDebug() << "key:" << key << "value:" << map.value(key); // ой, поиск за log(N)
}
// а потом жалуются что "qt тормозит"

А с задачей-то что? Может великое std имеет какие-то неведомые мне могучие средства чтобы достичь того же куда проще/эффективнее? Так пожалуйста, покажите, я ведь об этом и просил.
Так с std::unordered_map "задачи" бы не возникло - где хотите, там и объявляете функтор std::hash, никаких проблем.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #19 : Май 16, 2019, 16:49 »

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

На самом деле всё ещё проще: нет желания тратить время на Ваши "задачи" Улыбающийся.
Записан

Пока сам не сделаешь...
ssoft
Программист
*****
Offline Offline

Сообщений: 579


Просмотр профиля
« Ответ #20 : Май 16, 2019, 20:12 »

Еще 5 копеек про Qt контейнеры. На последнее встрече в Москве было объявлено, что, вероятно, Qt откажутся от поддержки собственных контейнеров в Qt6. Но это все еще обсуждается.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #21 : Май 17, 2019, 09:13 »

Да, он вставляет T(), потом самому данные надо вписать, не очень удобно. Ну хоть хвост (потенциально большой) сдвигается один раз.

Код:
// c++17
std::map<QString, QVariant> map;
for (auto&& [key, value]: map) {
    qDebug() << "key:" << key << "value:" << value;
}
Круто (червона рута). Но "killer feature" - да бог с Вами. Ну напишу тупенько с итераторами, не переломлюсь. Это всего лишь "красивая строка"

Так с std::unordered_map "задачи" бы не возникло - где хотите, там и объявляете функтор std::hash, никаких проблем.
Тут совсем не понял. Что за хвунктор и где его вставлять? Как это решит уникальность экземпляров? "Можно пример?"  Улыбающийся

Код:
// qt bad
QMap<QString, QVariant> map;
for (auto&& key: map.keys()) { // ой, аллокация и куча ref/deref строк
    qDebug() << "key:" << key << "value:" << map.value(key); // ой, поиск за log(N)
}
// а потом жалуются что "qt тормозит"
Да, есть такой грех, Qt "подкармливает лохов". Классический пример: QString::split. Так ляпать контейнерами НЕЛЬЗЯ. Но.. это ф-ция страшно удобна. Ну и что что "затратна" - зато можно "взять готовое и не париться!". И таких юзеров много, и их мнение "весит" столько же как и нормальных, понимающих. Так почему бы их не привлечь такими "удобными" вызовами? В конце-концов юзать никто не заставляет. По-хорошему спички keys() давать детям не следовало.
« Последнее редактирование: Май 17, 2019, 09:16 от Igors » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 579


Просмотр профиля
« Ответ #22 : Май 17, 2019, 12:47 »

Заглянул в пример).
QWeakPointer и CWeakPointer ни в коем случае не должны использоваться в виде ключа, так как не управляют своим состоянием. В любой момент метод data может начать возвращать nullptr вместо какого-либо значения. Weak должен быть сугубо значением. В качестве ключа следует использовать Raw указатель (Type *). То есть любой set для weak использовать нельзя.
Итератор у hash и set запоминать и в дальнейшем использовать бесполезно, так как в любой момент при изменении hash или set может быть перераспределение узлов и итераторы станут не действительными.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #23 : Май 17, 2019, 13:59 »

В любой момент метод data может начать возвращать nullptr вместо какого-либо значения.

Именно поэтому в std::weak_ptr нет метода get(). Из weak_ptr  доступ к объекту можно получить только принудительно продлив время его жизни с помощью lock(), чтобы не бояться, что объект в любой момент может превратиться в тыкву, если его грохнут из другого потока. Это к вопросу продуманности классов в std и Qt.
« Последнее редактирование: Май 17, 2019, 16:18 от ViTech » Записан

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

Сообщений: 3258


Просмотр профиля
« Ответ #24 : Май 17, 2019, 15:22 »

Круто (червона рута). Но "killer feature" - да бог с Вами. Ну напишу тупенько с итераторами, не переломлюсь. Это всего лишь "красивая строка"

Где ошибка?
Код:
const Item::PropertyMap &overriddenProperties = propertiesItem->properties();
for (Item::PropertyMap::ConstIterator it = overriddenProperties.constBegin();
    it != overriddenProperties.constEnd(); ++it) {
        loadedItem->setProperty(it.key(), overriddenProperties.value(it.key()));
}

Код:
for (const auto &kv : propertiesItem->properties()) {
    loadedItem->setProperty(kv.first, kv.second);
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #25 : Май 17, 2019, 18:53 »

Заглянул в пример).
QWeakPointer и CWeakPointer ни в коем случае не должны использоваться в виде ключа, так как не управляют своим состоянием. В любой момент метод data может начать возвращать nullptr вместо какого-либо значения.
Рассчитываю что перед этим должен сработать Deleter и до nullptr дело не дойдет.

Итератор у hash и set запоминать и в дальнейшем использовать бесполезно, так как в любой момент при изменении hash или set может быть перераспределение узлов и итераторы станут не действительными.
Этого я не проверял, из букваря видно что ++/--  меняются при rehash, ну думаю сам-то итератор валидный, иначе выходит что как у вектора "до первого милиционера" - наверняка написали бы. Ну это я так думаю  Улыбающийся

В качестве ключа следует использовать Raw указатель (Type *)
Интересная мысль. Но тогда как (или "из чего") отдать наружу шаред? Выходит weak нужен. Ну и шансов у (Type *) стать хламом столько же - только уже без проверки.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #26 : Май 17, 2019, 19:07 »

Где ошибка?
Код:
const Item::PropertyMap &overriddenProperties = propertiesItem->properties();
for (Item::PropertyMap::ConstIterator it = overriddenProperties.constBegin();
    it != overriddenProperties.constEnd(); ++it) {
        loadedItem->setProperty(it.key(), overriddenProperties.value(it.key()));
}
Не вижу прямой ошибки. Неясно зачем нужен еще поиск по ключу overriddenProperties.value(it.key()) если имеется итератор? Да и результат может быть разный если ключи не уникальны. Почему не it.value()?
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #27 : Май 17, 2019, 19:08 »

Не вижу прямой ошибки. Неясно зачем нужен еще поиск по ключу overriddenProperties.value(it.key()) если имеется итератор? Да и результат может быть разный если ключи не уникальны. Почему не it.value()?

Потому что лапша из итераторов и никто не замечал этого=)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #28 : Май 17, 2019, 19:13 »

Потому что лапша из итераторов и никто не замечал этого=)
Не вижу где, поясните. Ну а вообще что оте "итераторные сопли" всем уже осто<> - то я давно говорил (был заклеймлен в неграмотности  Улыбающийся)
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #29 : Май 17, 2019, 19:34 »

Не вижу где, поясните. Ну а вообще что оте "итераторные сопли" всем уже осто<> - то я давно говорил (был заклеймлен в неграмотности  Улыбающийся)

Итераторные сопли всем осточертели, это правда, и QMap::value прекрасный метод. Но его можно написать ручками в виде свободной функции и спокойно юзать std::map и не париться. А еще пачку других методов, чтобы не передавать в алгоритмы begin/end, а передавать контейнер целиком.
Другое дело, что вместо итераторных соплей или хелпер-функций люди начинают итерироваться по keys() или values() и рассказывать всем какие же удобные кутешные контейнеры.
Или делают if (map.contains(key)) return map.value(key);
Записан
Страниц: 1 [2] 3 4 5   Вверх
  Печать  
 
Перейти в:  


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