Название: [РЕШЕНО] константная ссылка в foreach Отправлено: deMax от Январь 21, 2016, 14:58 мне нравится foreach красотой и компактностью, с другой стороны зачем он возвращает ссылку константу?
Код: QList<int> ls; ls<<1<<2<<3; Название: Re: константная ссылка в foreach Отправлено: __Heaven__ от Январь 21, 2016, 15:01 c++11
Код
Название: Re: константная ссылка в foreach Отправлено: deMax от Январь 21, 2016, 15:14 Спасибо.
А что скажете про C++11? стоит его включить для Qt5, проблем не возникнет? Название: Re: константная ссылка в foreach Отправлено: __Heaven__ от Январь 21, 2016, 15:16 У меня пока не возникало
Название: Re: константная ссылка в foreach Отправлено: Alex Custov от Январь 21, 2016, 15:20 использовать const_cast и модифицировать const данные - это UB, насколько я помню. Решение - использовать сишный "итератор" по индексам, или C++11, как написал __Heaven__
Название: Re: константная ссылка в foreach Отправлено: deMax от Январь 21, 2016, 15:30 Итератор слишком громоздкая запись(для задачи пройтись по всем элементам он точно не нужен).
ub не будет, потому что ссылка не обязана быть константой, а foreach так требует, хотя это неверно. Название: Re: константная ссылка в foreach Отправлено: __Heaven__ от Январь 21, 2016, 15:34 Ну вам в стандарте 0х всё-таки единственный путь - итераторы.
что такое ub? Название: Re: константная ссылка в foreach Отправлено: deMax от Январь 21, 2016, 15:37 ub - Undefined behavior(Неопределённое поведение). В данном случае все будет нормально, даже в бусте он не такой кривой:
Код: QList<QString> a; BOOST_FOREACH(QString& s, a) s += "s"; Название: Re: константная ссылка в foreach Отправлено: __Heaven__ от Январь 21, 2016, 15:39 Undefined behavior Тьфу, блин. University at Buffalo Так используйте тот, что в бусте. Ну или свой определите. Название: Re: константная ссылка в foreach Отправлено: deMax от Январь 21, 2016, 15:50 так правильнее:
Код: QList<int> ls; ls<<1<<2<<3; буст тяжеловат будет, проще const_cast использовать, может со временем в qt исправят эту ошибку. p.s. с++11 хорош, надо будет как нибудь перейти. Название: Re: константная ссылка в foreach Отправлено: __Heaven__ от Январь 21, 2016, 15:54 deMax, уж лучше сделайте на итераторах. Точно наступите на грабли когда-нибудь с const_cast.
Название: Re: константная ссылка в foreach Отправлено: kambala от Январь 21, 2016, 17:36 так правильнее: то есть это лучше, чем использовать индексы? ок.Код: QList<int> ls; ls<<1<<2<<3; Название: Re: константная ссылка в foreach Отправлено: ssoft от Январь 22, 2016, 08:37 Реализация foreach в Qt несколько криворукая и имеет описанные ограничения, часто уступает в производительности простому for через итераторы или индексы.
Вот в boost реализация оказалась отличной и без описанных ограничений. Но не тащить же еще и boost ;D Такое кастование - это зло, которое нужно срочно искоренить из проекта! К слову из-за того, что реализация QList implicit shared, таким кодом вы корректируете все взаимосвязанные с данным списком данные. Если есть необходимость изменения данных в массиве QList, то необходимо использовать либо индексы, либо итераторы, либо C11, либо еще что-то, но никогда кастование! Название: Re: константная ссылка в foreach Отправлено: deMax от Январь 22, 2016, 09:18 Я где то тесты видел что foreach не уступает в производительности итераторам, да и не такие большие вычисления у меня в foreach.
итераторы вещь хорошая, но когда идет последовательный перебор получается слишком много бестолкового кода в котором еще и опечататься можно, особенно если list какое нибудь длинное выражение) >> К слову из-за того, что реализация QList implicit shared, таким кодом вы корректируете все взаимосвязанные с данным списком данные. В моем случае будет нормально, хотя спасибо что предупредили. Наверно буду на с++11 переходить. p.s. только что создал вектор и список на 1E7 элементов, заполнив единицами, int с=1 изначально Код: foreach(const int &i, list1) { count*=i; } Код: QVector<int>::Iterator it1; for (it1 = list1.begin(); it1 != list1.end(); ++it1) count*=*it1; результат: для foreach (вектор 70мс список 200) итераторы (вектор 570 список 470) в режиме отладки в режиме выпуска все примерно равны(добавил for из с++11): vector (foreach 150 / for 150 / iterator 190) list (foreach 200 / for 150 / iterator 170) время в мс из QTime::elapsed() Название: Re: константная ссылка в foreach Отправлено: Old от Январь 22, 2016, 09:22 Вы ограничены в выборе компилятора? Если нет, то используйте c++11. Для чего использовать конструкцию, которая пытается имитировть for, если есть сам for? :)
Название: Re: константная ссылка в foreach Отправлено: Igors от Январь 22, 2016, 10:42 К слову из-за того, что реализация QList implicit shared, таким кодом вы корректируете все взаимосвязанные с данным списком данные. Почему? Код Да, const_cast, но ведь все равно выполняется оператор [], он возвращает неконстантную ссылку, значит расшарит данные Edit: A! Так foreach использует константный итератор - тогда да, никакого расшаривания не будет. Так это ж hidden feature! :) Название: Re: константная ссылка в foreach Отправлено: deMax от Январь 22, 2016, 11:11 Вот это штука "implicit shared" сильно на производительности сказывается или как? Можно ее отключить?
А что у нас есть вместо QVector/Qlist... только std::vector? Как перед foreach расшарить данные, чтобы были в единственном экземпляре? Сделали бы в Qt не константный foreach который бы и расшаривал. Название: Re: константная ссылка в foreach Отправлено: Igors от Январь 22, 2016, 11:27 Вот это штука "implicit shared" сильно на производительности сказывается или как? Можно ее отключить? Любой вызов неконстантного метода (напр ls[0]) вызовет расшаривание. По поводу форычаА что у нас есть вместо QVector/Qlist... только std::vector? Как перед foreach расшарить данные, чтобы были в единственном экземпляре? Сделали бы в Qt не константный foreach который бы и расшаривал. Код Чего не хватат? Чего неймется, к чему поиск "более элегантных" решений, обычный рез-т которых = 1 строка вместо 2, зато капитально заморочить яйца читающему код? Ей-богу, фигней занимаетесь :'( Название: Re: константная ссылка в foreach Отправлено: ssoft от Январь 22, 2016, 12:04 Если вы используете такой вариант
Код
то values не вызывает проверку того, что он shared. Данные будут изменены в обобщенном списке. Для выполнения detach() необходимо вызвать любой не константный метод values. И ... "implicit shared" сильно на производительности сказывается, так как не выполняются лишние копирования данных списка. Название: Re: константная ссылка в foreach Отправлено: deMax от Январь 22, 2016, 12:49 >>Чего не хватат? Чего неймется
у Вас lst 2 раза используется, если это будет функция класса(peoples.getMen(Vasia Pupkin).getHand.getFingers()) получим копипаст или дополнительную строчку Да я только что узнал про эту "великую фичу"(думал такая ерунда только в QSharedPointer), сижу в шоке - мне она как собаке пятое колесо :( Вещь в принципе неплохая, и на производительности современных ПК не скажется, скорее даже лучше станет - т.к. код можно писать более грязно(в стиле си шарпа). p.s. всем спасибо, буду переходить на C++11. Название: Re: константная ссылка в foreach Отправлено: deMax от Январь 22, 2016, 14:02 >>Чего не хватат? Чего неймется у Вас lst 2 раза используется, если это будет функция класса(peoples.getMen(Vasia Pupkin).getHand.getFingers()) получим копипаст или дополнительную строчку Да я только что узнал про эту "великую фичу"(думал такая ерунда только в QSharedPointer), сижу в шоке - мне она как собаке пятое колесо :( Вещь в принципе неплохая, и на производительности современных ПК не скажется, скорее даже лучше станет - т.к. код можно писать более грязно(в стиле си шарпа). Хотя частичная вина этой штуки тоже есть, что Qt такой тормознутый и жирный. p.s. всем спасибо, буду переходить на C++11. |