Как стать автором
Обновить

Комментарии 41

QMap умеет возвращать ключ по значению.
Скорее всего это и было препятствием в быстрой реализации.

Key QMap::key(const T &value, const Key &defaultKey = Key()) const

QMap умеет возвращать ключ по значению.

Не спорю

Скорее всего это и было препятствием в быстрой реализации.

В реализации чего?

#include "common/json/my_json.h

Это только для вывода в qDebug QVariantMap в более читабельном виде (json строка с переносам и т.д.)

Что это? И почему уровень статьи "сложный"?

Не придирайтесь, какой уровень по вашему?

Я не придираюсь. Просто посмотрите другие статьи на Хабре про C++ с уровнем "сложный". Для начала, на их объем, и на содержание.

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

Но в дань уважения к Qt фреймворку в целом (что они предложили миру мы считаем, что можно немного подправить QMap для предоставления лучшей функциональности.

Так что мы считаем-то? Где закрывающая скобка? И т.д. по всему тексту.

Где закрывающая скобка?

Да спс ,не скомпилируется

Я не про код, а про эту фразу: "Но в дань уважения к Qt фреймворку в целом (что они предложили миру" - открывающая скобка есть, закрывающей нет, явно что-то пропущено.

Я не про код, а про эту фразу

Я понял, шучу так

В Qt 6.6 добавили методы get/get_if для получения типизированных ссылок на внутренний элемент QVariant

Это должно решить проблемы работы с копиями.

добавили методы get/get_if для получения типизированных ссылок на внутренний элемент QVariant

Спасибо! Хорошая новость, хоть что-то начинает меняться в Qt. Но для меня опять получается не повод переходить на Qt6 (т.к. сам навелосипедил, а свое ближе к ...)

Это должно решить проблемы работы с копиями.

Чего-то сомнения взяли должно или решили? Не знаете?

Я не работал с версией выше 6, поэтому не могу сказать наверняка.

Давно не писал на Qt, но вроде проблема из-за использования именно класса QVariantMap. Вот так должно работать:

QMap<QString, QMap<QString, QMap<QString, QVariant>>> map;
map["map1"]["map2"]["prop"] = "value123";

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

Также у вас будет неопределенное поведение, если в значении лежит не QpMap<QString,QVariant>, а другой тип, который может конвертироваться в него. Лучше смотреть, какой конкретно тип лежит в QVariant, используя QVariant::userType() или схожие методы.

Map<QString, QMap<QString, QMap<QString, QVariant>>> map;
Но это если вы всегда храните значения только по такой структуре дерева.

Да, в это и есть проблема, надо заранее дерево планировать.

Лучше смотреть, какой конкретно тип лежит в QVariant

Да конечно обязательно и там (в QpMap) проверяется методом canConvert.

Я про это и говорю. Я могу создать какой-нибудь свой класс MyVariantMap и потом добавить конвертер через QMetaType::registerConverter<MyVariantMap, QVariantMap>(). Тогда вызов QVariant::fromValue(MyVariantMap{}).canConvert(QVariant::Map) будет возвращать истину, хотя внутри лежит не QVariantMap. Поэтому метод canConvert() для этой цели использовать нельзя.

Поэтому метод canConvert() для этой цели использовать нельзя.

Спасибо учту

QVariant::userType()

Да еще раз спасибо, поправил проверку на тип по QVariant::userType() . Заодно добавил возможность добавлять QVariantList по ключу как элемент в QVariantMap.

Qt4

На дворе 2024 год...

На дворе 2024 год...

Не хочется разводить флуд, но мне кажется что в этой маленькой статейке и есть ответ. То есть не смотря на то какой год в Qt приходится вставлять очевидные костыли.

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

Вольдэмар все по делу написал)

зачем он использовал Qt

так исторически сложилось (наверное надо было быстро сделать готовое приложение). Qt это самодостаточный фреймворк.

 А потом бустовики будут ржать

А есть в буст готовый набор Core,Gui,Network,Svg, чтобы получить готовое приложение за день? Как я понял буст это всего лишь часть (библиотека, хоть и наверное во многом лучшая). Вы Гуй как отрисовываете?

QMap - это часть Core, никакого отношения к гуи не имеет. Нет никакого смысла зацикливаться именно на ней, если нужна та самая избыточная производительность (напоминаю, что это мотивация появления сего костыля). И я открою секрет, нет никакого запрета на использование других библиотек при использовании Qt. Я вот в своём приложении (QML, Qt5 для win7, Qt6) использую CImg как обработчик изображений и libtiff, libpng, libjpeg, хотя мне же доступен QImage, да? Также вообще не вижу никакой необходимости использовать контейнеры из Core, когда есть современная STL. Это уже не говоря о том, что можно не зацикливаться на плюсах

Все эти отмазки про "исторически сложилось" вопреки всему вызывают только смех, выдают некомпетентность пишущего. Наверное, среди них есть и отмазка, почему надо использовать Qt4 в 2024 году (я вот не могу придумать). И самое главное, вообще не понятно, зачем всё это костылить и ещё карябать аж целую статью.

Надо работа с JSON - просто берешь подходящую либу, а не забиваешь этот шуруп с помощью QMap.

И да, готовое "приложение за день" я гораздо быстрее напишу на шарпе, а не на плюсах. Проблема только в том, что за день они не пишутся. И если приложение написано так, что в 2024 году его всё еще нужно пилить на Qt4, даже не представляю, что там за дичь. У меня встречались случаи разной запущенности, но всё успешно апгрейдилось.

Опять вы про Qt4 пишете… Современными компиляторами он собирается? Патчи безопасности для него выходят? Деплой собранных приложений без костылей поддерживается? Современные ОС с HiDpi поддерживаются? Стандартные темы современных ОС поддерживаются? Сигланы-слоты без строковой макросни есть?

Я правильно понимаю, что вы на работе поддерживаете какой-то лютый легаси проект и боитесь даже посмотреть на то, как развилась Qt за последние 10 лет?

По сабжу, возьмите бустовый проперти три и не откапывайте стюардессу. Из да, контейнеры в Qt тоже очень прилично поменялись со времен 4-й версии.

В последних C++ контейнеры std::map/std::multimap не позволяют решить поставленную задачу?

А какая задача поставлена? Если я правильное понял, автор изобретает синтаксический сахар для того, что писалось ещё под с++98.

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

Ну так написано же:

Решаем одну старую проблему с QMap.  Если у вас в программе только один QMap (map1), то вы можете спокойно с ним работать: добавлять (insert), изменять(тоже insert), удалять(remove) элементы в контейнере без проблем.

Для конкретности предположим, что мы работаем с QVariantMap контейнером. Если мы теперь создаем второй экземпляр QVariantMap контейнера (map2) и делаем его вложенным в первый QVariantMap контейнер, то теперь мы уже не можем просто взять и изменить элементы второго QVariantMap контейнера (map2). Точнее мы можем только взять второй QVariantMap контейнер по ключу из первого контейнера, потом изменить и далее придется полностью заменить второй контейнер в дереве.

Если я правильно понимаю, нужно доступиться до узла map по ключу и заменить в нем содержимое, не перестраивая заново всю структуру.

Да, и для того чтобы написать a[k]=v понадобилась целая статья.

Как я понял там больше про то что автор не знает про std::map/std::variant и рассказывает про свой велосипед.

Я так понимаю, велосипед связан с тем, что он использует QT. А что, при использовании QT можно использовать только QMap, а std::map, в который засунуты типы из QT, разве нельзя? Например:

std::map<QString, std::map<QString, std::map<QString, QVariant>>> map;

Велосипед связан с тем что в реализации Qt4 нет нужных операторов для QVariant. А вместо решения проблемы автор пытается приспособить не предназначенные для этого классы.

автор не знает про std::map/std::variant 

это правда (но теперь буду знать), но в этой статейке подняты 2 вопроса как получается:
1. Почему в Qt4 такую возможность не предоставили?
2. И в Qt 5,6 что-то изменилось в QMap (по сравнению в Qt 4)?

Попробуйте почитать документацию. В том числе об изменениях между Qt4 и последующих. Впрочем Qt4 настолько стар, что доки по нему даже с официального сайта убрали.

По поводу вашей изначальной проблемы - вы пытаетесь натянуть сову на глобус. А когда сова не налазит - вы пишете что мол Qt плохой. Исправлять в вашем случае нужно не QMap, а QVariant. Но ещё более правильное решение - взять готовый инструмент, который предназначен как раз для таких задач. Или чтобы сова таки налезла, вам надо взять Qt 6.6 или новее, там есть шаблонный QVariant::get который вернёт ссылку на внутреннее представление.

Чтобы более предметно пообщаться - ответьте на вопросы в моём корневом сообщении. (Хотя я знаю, что не сможете, но вас это не переубедит в том что Qt4 устарел и в современным мире есть получше решения).

Опять вы про Qt4 пишете… Современными компиляторами он собирается?

msvc-2010 билдим

Патчи безопасности для него выходят?

Код открыт, если чего надо можно всегда добавить (к примеру TLS1.2), это не то чтобы сложно

Деплой собранных приложений без костылей поддерживается?

Статикой собираю x86, никаких зависимостей. Win7,10 работает стабильно (только если сам накосячил в коде).

Я правильно понимаю, что вы на работе поддерживаете какой-то лютый легаси проект

Меня тут уже забанили за рекламу (я вам в личку напишу)

контейнеры в Qt тоже очень прилично поменялись со времен 4-й версии.

хорошая новость, и под какой стандарт (год) С++ они заточены?

Ну то есть в большинстве случаев резюме такое: Qt4 не используется и статьи про это должны быть из разряда "у меня хобби программировать под вин3.11" (тут где-то были статьи про движок который собирается на старых платформах).

По сабжу: код то открыт, но получается что вы сами себе единственные мейнтейнеры. И приложение пишете и кутэ дорабатываете и собираете сами. У вас CI/CD есть на проекте (для самого проекта и для сборки кутэ)? Деплой как делаете, просто ручками библиотеки рядом с .exe кладёте? Если всё вручную - то это далеко не пример того, как надо разрабатывать, но это ваше дело :)

В любом случае ответа на вопрос "зачем поддерживать это старьё" всё равно нет. Как и ответа на вопрос "зачем решать проблему которую вы сами себе придумали".

QVariantMap вам зачем в качестве значения? Чтобы проверить есть ли внутри вложенная структура или нет? Сериализацию делаете или надо json-о подобные структуры парсить? Почему boost::property_tree не взяли?

У вас CI/CD есть на проекте (для самого проекта и для сборки кутэ)?

У меня все просто - отлаживаю новую версию в дебаге, потом переключаюсь на статику (1мин) и собираю один exe-ник, далее батником его подписываю (своим центром сертификации), там же инсталлер создаю и загружаю на сайт.

Деплой как делаете, просто ручками библиотеки рядом с .exe кладёте?

Один exe , все библиотеки также статически собираются ( openssl и т.д.), все в один exe -ник.

QVariantMap вам зачем в качестве значения?

Просто первое, что подвернулось под руку. На входе принимаем данные по единому протоколу json (нами придуманный) и конвертируем в нативные для разных моделей кассовых аппаратов.

О, то есть на лицензии Qt и OpenSSL вам пофиг? Или у вас всё куплено?

Ну вот мы и пришли к пониманию того что вам надо. Вам надо парсить и собирать json-ы. В общем, уже в который раз намекну на то что есть нормальные парсеры json-ов, в том числе готовые и достаточно удобные классы в Qt. Отсюда в очередной раз возникает вопрос - зачем нужно то, что вы описали в статье?

И да, вы забыли ответить почему вам проперти три, который решает все ваши задачи, не подошёл.

О, то есть на лицензии Qt и OpenSSL вам пофиг?

Могу об'ектные файлы для сборки предоставить, если это кому-то понадобится.

А покупать не собираюсь, тогда уже проще свой фреймворк с нуля написать, на самом деле там не так уж и сложно разобраться

Уверены что проще?

И я в пятый раз спрашиваю, почему вы не взяли покрытый тестами, удобный и бесплатный boost::property_tree который на 100% закрывает вашу задачу, а решили изобрести кривой велосипед?

удобный и бесплатный boost::property_tree который на 100% закрывает вашу задачу

Знать не знал, теперь буду знать

Интересно, может я еще много чего не знаю. А нет ли в бусте готового фреймворка типа как Qt? Им и флаг в руки, если действительно они могут делать частями лучше, почему им не родить такой фреймфорк?

Задачи разные решаются. В бусте практически отсутствуют платформозависимые части. Или вам нужна именно одна универсальная библиотека, которая готова дать ответ на главный вопрос жизни, вселенной и всего прочего?

P.S. В Qt тоже есть достаточно удобные классы для работы с json. Можно и без буста.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории