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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Насколько тяжёл будет foreach по наследнику QStringList  (Прочитано 6820 раз)
DarkHobbit
Самовар
**
Offline Offline

Сообщений: 197


Просмотр профиля
« : Октябрь 05, 2016, 06:42 »

Доброе утро.
Создал я свой класс, наследника QStringList. И понадобилось пробежаться по его элементам (не изменяя, только читая). Недолго думая, написал
Код:
foreach(const QString& s, myList)
Получил кучу ошибок. Странно, думаю, с самим QStringList проблем никогда не было.
Наткнувшись на сообщение об отсутствии копирующего конструктора, понял, что макрос пытается сделать копию объекта.  Даже пытается синтезировать этот копирующий конструктор, но спотыкается об объект класса QSettings, который является был Улыбающийся одним из полей моего класса, а у QSettings копирующий конструктор приватный.
Перечитал справку. Действительно:
Цитировать
Qt automatically takes a copy of the container when it enters a foreach loop
Ниже, правда, в утешение говорится:
Цитировать
(If you do not modify the container, the copy still takes place, but thanks to implicit sharing copying a container is very fast.)
Почитав бегло главу про этот самый implicit sharing copying, я понял, что разработчики Qt добивались его специально, и даже приводится список классов, в которых оно поддерживается.

От QSettings в полях я избавился (он там был нужен только для пары методов, и я его перенёс), и программа собралась. Но осадочек в голове остался.

Собственно, вопрос: а вообще-то, в моём классе будет работать быстрое копирование, или будет делаться deep copy, а я об этом никогда не узнаю? Может, быстрее и надёжнее будет обычный, хотя и топорный for по элементам списка? Или можно выполнить какие-то условия, чтобы в моём классе-наследнике быстрое копирование тоже работало, и если да, то какие?

Версии Qt, под которыми собирается мой проект - от 4.6.0 до 5.6.1.
« Последнее редактирование: Октябрь 05, 2016, 06:52 от DarkHobbit » Записан

Мои проекты на Qt: DoubleContact, LInvert
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #1 : Октябрь 05, 2016, 08:24 »

Собственно, вопрос: а вообще-то, в моём классе будет работать быстрое копированиеПо скорости , или будет делаться deep copy, а я об этом никогда не узнаю?

Сначала про копирование.  Реализация implicit shared сущностей  подразумевает копирование только в момент вызова не константных методов. Если их вызов не предвидится, то уже у нового QStringList данные всегда будут неявно разделены с исходным.

Может, быстрее и надёжнее будет обычный, хотя и топорный for по элементам списка?

Надежнее будет та реализация, которая более понятна, foreach введен для удобства. По скорости реализация Qt уступала обычному for примерно 25-50%, в то время как реализация boost не уступала совсем (я проводил бенчмарки на Qt 4.7.4). А вообще пора переходить на новый стандарт языка Смеющийся

Код
C++ (Qt)
for( QString string : string_list)

Или можно выполнить какие-то условия, чтобы в моём классе-наследнике быстрое копирование тоже работало, и если да, то какие?

Независимого механизма implicit shared в Qt не предложено. Возможно наследование своих структур от QSharedData и использование QSharedDataPointer.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #2 : Октябрь 05, 2016, 08:44 »


Код
C++ (Qt)
for( QString string : string_list)


Код
C++ (Qt)
for( const auto &string : qAsConst(string_list))
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Октябрь 05, 2016, 08:59 »

Может, быстрее и надёжнее будет обычный, хотя и топорный for по элементам списка?
Интересно наблюдать как эти остатки здравого смысла будут безжалостно задавлены Улыбающийся Копирующий конструктор, имплисит шара, новый стандарт, и, наконец, последний писк моды qAsConst. И чему же все это посвящено? Избежать for - он уже "топорный". А почему? Ну могут подумать что, мол, мало знаю, "не владею" и все такое...

Вы бы голову-то пожалели, жалко тратить ее на такую фигню как форыч
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #4 : Октябрь 05, 2016, 09:46 »

Интересен foreach, как и auto, становится тогда, когда обычная запись "замусоривает" восприятие кода (особенно, если используется мета программирование на шаблонах)

Например, простейший код

Код
C++ (Qt)
std::unordered_map< Key, Value > container;
...
for ( std::unordered_map< Key, Value >::iterator iter iter = container.begin();
   iter != container.end(); ++iter )
{
   ...
}
 

может быть реализован так


Код
C++ (Qt)
typedef std::unordered_map< Key, Value > Container;
Container container;
...
typedef Container::iterator Iterator;
for ( Iterator iter = container.begin();
   iter != container.end(); ++iter )
{
   ...
}
 

а может  так

Код
C++ (Qt)
using Container = std::unordered_map< Key, Value >;
Container container;
...
for ( auto & pair : container )
{
   ...
}
 

что просто облегчает чтение и позволяет сфокусироваться на сути. А так дело привычки  Подмигивающий
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Октябрь 05, 2016, 09:50 »

что просто облегчает чтение и позволяет сфокусироваться на сути. А так дело привычки  Подмигивающий
Согласен конечно, но все хорошо в меру  Улыбающийся
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #6 : Октябрь 05, 2016, 09:58 »

Код
C++ (Qt)
for( const auto &string : qAsConst(string_list))

а разве просто
Код
C++ (Qt)
for (auto s: somestringlist)

будет не достаточно ?
тип s должен быть QString const&
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #7 : Октябрь 05, 2016, 11:49 »


а разве просто
Код
C++ (Qt)
for (auto s: somestringlist)

будет не достаточно ?
тип s должен быть QString const&


Нет, с++11 for вызывает неконстантные begin/end, а они вызовут детач контейнера.
UPD: нет, тип auto будет QString

Интересно наблюдать как эти остатки здравого смысла будут безжалостно задавлены Улыбающийся Копирующий конструктор, имплисит шара, новый стандарт, и, наконец, последний писк моды qAsConst. И чему же все это посвящено? Избежать for - он уже "топорный". А почему? Ну могут подумать что, мол, мало знаю, "не владею" и все такое...

Вы бы голову-то пожалели, жалко тратить ее на такую фигню как форыч

Да, имплисит шару в контейнерах надо закопать, но не поэтому, а потому что с ними невозможен мув объекта внутрь контейнера (QVector<std::unique_ptr> сделать нельзя)
« Последнее редактирование: Октябрь 05, 2016, 15:09 от Авварон » Записан
DarkHobbit
Самовар
**
Offline Offline

Сообщений: 197


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

Всем спасибо за ответы.
Пожалуй да, в сомнительных случаях стоит использовать обычный for.
Половина ответов сводится к рекомендации задействовать for из C++11. Я этот вариант обдумываю, я понимаю, что рано или поздно на него перейду, но пока не готов отказаться от совместимости со старым стандартом, ибо есть экзотические, но интересные для меня платформы, на которые в 2016 году всё ещё не завезли C++11.
Записан

Мои проекты на Qt: DoubleContact, LInvert
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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