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

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

Страниц: 1 2 [3] 4 5 ... 8   Вниз
  Печать  
Автор Тема: Как заменить неизвестное заранее число вхождений в QRegExp ?  (Прочитано 56726 раз)
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #30 : Июнь 08, 2016, 13:32 »

Цитировать
Ну ок, итераторы там (хотя на что?
Это даёт Вам возможность адаптировать алгоритм для любого контейнера, который поддерживает bidirectional итераторы, т.е. такие, которые могут бегать по последовательности в обоих направлениях: http://en.cppreference.com/w/cpp/concept/BidirectionalIterator

Цитировать
что есть входными и выходными параметрами для них?
OutIter out - входной итератор:
 BidiIter begin - начало исходной последовательности:
 BidiIter end - угадайте)

Цитировать
какой тип данных? какие контейнеры?
В том то всё и оно, что Вы можете использовать хоть std::string хоть std::vector<char>, хоть QString, хоть вообще левую реализацию Васи Пупкина. Главное чтоб последовательность поддерживала bidirectional итераторы.

Цитировать
Надо ли мне иметь уже преалоцированный контейнер для результатов или оно "само сделается"?)
 
Не уверен, надо почитать..

Цитировать
Ок, рыгэксп надо задавать какими-то биде-итераторами... Ни примеров, ни-че-го  Обеспокоенный
 
Опять же, это сделано для того, чтобы Вы могли прикрутить регулярку для любой реализации строк.

Вот Вам простой пример использования (из гугла):
Код
C++ (Qt)
using boost::xpressive;
 
std::string modifyString(const smatch& match){
   std::string out(match[1]);
   std::reverse(out.begin(),out.end());
   return out;
}
 
 
   std::string in("a(bc) de(fg)");
   sregex re = +_w >> '(' >> (s1= +_w) >> ')';
   std::string out = regex_replace(in, re, modifyString);
   std::cout << out << std::endl;
 
 

Цитировать
То есть, оно таки берет и тупо копирует кусок памяти (с аллокациями и т.д.), а потом вызывает форматтер... Приехали к тому, что обсуждалось выше  Грустный
С чего Вы взяли, что алгоритм std::copy занимается аллоцированием? Он просто копирует одну последовательность: m.prefix().first, m.prefix().second в выходную out. http://en.cppreference.com/w/cpp/algorithm/copy

Цитировать
Самое веселое - API данного форматера я так и не увидел, покажите...?
Сигнатура форматера зависит от того, с какой последовательностью Вы работаете. Например для std::string:
Код
C++ (Qt)
std::string my_formatter(const smatch &)
 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #31 : Июнь 08, 2016, 14:31 »

А что в этом плохого? Да, буст это инструмент, гибкий и отлично продуманный. Там можно подсмотреть не мало концептов и решений. И понимание и изучение их гораздо более полезнее для собственного развития, чем написания велосипедов в стиле C с классами. )
Мои наблюдения за Вашим развитием (точнее регрессом) этих выводов о полезности не подтверждают Улыбающийся

Свежий пример
Вот Вам простой пример использования (из гугла):
Код
C++ (Qt)
using boost::xpressive;
 
std::string modifyString(const smatch& match){
   std::string out(match[1]);
   std::reverse(out.begin(),out.end());
   return out;
}
 
 
   std::string in("a(bc) de(fg)");
   sregex re = +_w >> '(' >> (s1= +_w) >> ')';
   std::string out = regex_replace(in, re, modifyString);
   std::cout << out << std::endl;
 
 
Что человек извлекает из этого? Ну надо запомнить "+_w" и "s1", и, конечно, как вызывать. Потом у себя в тексте повторить. УСЕ. Какие нафиг "концепты"? Тупенькая запоминаловка рулит Улыбающийся
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #32 : Июнь 08, 2016, 15:09 »

Вот сказу честно: как мне кажется, буст - это отличный пример оверинжиниринга и антипаттернов Gas factory и Soft code. Главная проблема буста - он не является проблемно-ориентированной библиотекой, а представляет из себя набор слабо связанных между собой модулей. То есть для того, чтобы РЕШИТЬ с его помощью определенную задачу, надо потратить битый час на то, чтобы разобраться с архитектурой и параметризацией. Действительно ли хочет этого заказчик? Или ему нужно решение проблемы наиболее эффективным способом?

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

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #33 : Июнь 08, 2016, 16:00 »

Вот сказу честно: как мне кажется, буст - это отличный пример оверинжиниринга и антипаттернов Gas factory и Soft code. Главная проблема буста - он не является проблемно-ориентированной библиотекой,
Ну вообще-то есть и др направления кроме ООП. Никогда не общались напр с поклонниками хаскеля (ФП - ф-циональное программирование)? О-ооо  Улыбающийся

Основной мой вопрос: оправдывает ли себя погружение в буст с т.з. производительности полученной программы? Насколько хороши заложенные в него решения для того, чтобы пренебречь читаемостью и пониманием кода?
Вот кстати о последнем. Почему-то все промолчали, а мне бросилось в глаза
Код
C++ (Qt)
template <class FormatFunc>
QString regex_replace
Кто такой FormatFunc? Хз. Что принимает и что возвращает? Хз. Что он должен делать по замыслу автора? Хз. Все это надо выковыривать в коде по крупицам. Якобы "для достижения большей гибкости". А по-моему простецкий коллбэк
Код
C++ (Qt)
typedef QString (*ReplaceFunc)( const QRegExp &);  // c QRegExp
// или
typedef QString (*ReplaceFunc)( const QStringRef & ref );  // без QRegExp
 
был бы и яснее и мощнее. Ах, это не будет работать с std::string и.т.п.!!! ("морковка общности" суется в нос). Да пофиг ветер, придет задача с std::string - тогда и будем думать, и решения найдутся получше таких трудоемких как "все только общее".

Да, и где здесь "концепции"? Повторение увиденной схемы без единой своей мысли - и то технически неудачное.
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #34 : Июнь 08, 2016, 17:20 »

Ну вообще-то есть и др направления кроме ООП.

Не, я имел в виду не ООП, а проблемую ориентацию.
Ну т.е. существуют библиотеки алгоритмов (например, SimdLib), которые решают достаточно четкие задачи - как правило, подается вход и набор параметров, а на выходе - решение. API выглядит обычно приблизительно так:

Result& DoSomething(const Input& in, const Params& params);

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

А насчет общности - а всегда ли она нужна? Существуют же YAGNI и KISS для чего-то Улыбающийся

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

« Последнее редактирование: Июнь 08, 2016, 17:25 от Racheengel » Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #35 : Июнь 08, 2016, 18:34 »

Да, возвращаясь к теме. Есть метод
Цитировать
QString & QString::replace(const QRegExp & rx, const QString & after)
Наверное самым четким решением был бы еще метод
Цитировать
typedef QString (*ReplaceFunc)( const QRegExp & rх ); 
QString & QString::replace(const QRegExp & rx, ReplaceFunc rep);
Чтобы подставлять то что выдаст функтор, а не тупо константу.

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

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #36 : Июнь 08, 2016, 18:57 »

С темплейтами в C++ несколько больших проблем, главные из них:
- разные компиляторы их до сих пор "понимают" несколько по-разному (возьмем студию и gcc, например);
- не всегда однозначно можно понять, что подразумевал автор;
- в разы замедляется время компиляции;
- ухудшаются возможности по оптимизации кода.

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

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #37 : Июнь 08, 2016, 23:32 »

Цитировать
Мои наблюдения за Вашим развитием (точнее регрессом) этих выводов о полезности не подтверждают  Улыбающийся
Да ну.. на оценку Вашего мнения в отношении себя мне фиолетово  Улыбающийся Так что, с позволения Вашего Величества, оставлю без комментариев подобные выпады)

Цитировать
Свежий пример
...
Что человек извлекает из этого? Ну надо запомнить "+_w" и "s1", и, конечно, как вызывать. Потом у себя в тексте повторить. УСЕ. Какие нафиг "концепты"? Тупенькая запоминаловка рулит  Улыбающийся
Т.е. Вы признаёте, на сколько просто с помощью буста можно решать подобные задачи, даже человеку, не слишком посвященному в тонкости и всякие концепты?
А теперь посмотрим на следующий пример:
Код
C++ (Qt)
QString str = "text text <span></span> cd(ab) <a href="http://www.prog.org.ru/index.php?action=search;advanced"><img src="http://prog.org.ru/Themes/default/images/filter.gif" align="middle" style="margin: 0 1ex;" alt="" /></a>";
QString out = ReplaceBlanks(str);
 
Так что же простой пользователь извлекёт из этого? Что я, как конечный пользователь, должен подумать? Для меня этот Ваш ReplaceBlank ровно ни о чём не говорит.. И более того, он решает лишь одну очень частную задачу (в том случае, если пользователь всё же догодается для чего он нужен).. Достаточно слегка изменить условие и никто, кроме, возможно Вас, не станет разбираться, а тем более, переписывать это всё под новую задачу.

Цитировать
Вот сказу честно: как мне кажется, буст - это отличный пример оверинжиниринга и антипаттернов Gas factory и Soft code. Главная проблема буста - он не является проблемно-ориентированной библиотекой, а представляет из себя набор слабо связанных между собой модулей. То есть для того, чтобы РЕШИТЬ с его помощью определенную задачу, надо потратить битый час на то, чтобы разобраться с архитектурой и параметризацией. Действительно ли хочет этого заказчик? Или ему нужно решение проблемы наиболее эффективным способом?
Ну откуда такие комплексы и страх перед всем новым? Вы знаете, Racheengel, я честно скажу - я не програмист.. Программирование не является моей работой, а скорее побочным эффектом.. И к кодингу я всячески стараюсь пребегать только тогда, когда уже без этого ну никак нельзя.. Но.. Но я, тем не менее, не вижу никакой проблемы по части разобраться как и что устроено в бусте, если мне это интересно и действительно нужно.. Да, там на начальных порах нужно преодолеть некий барьер вхождения.. Но зато потом это окупиться) Вы с igors'ом же, похоже, не разобравшись, имея лишь поваерхностное представление (уверен Вы даже и не подозревали о категориях итераторов) вот так просто делаете достаточно категоричные суждения и выводы..
Я Вам привёл доводы в пользу буста, как инструмента, который можно адаптировать под разные нужды/типы/контейнеры и т.д.. Какие из лично Ваших решений обладают таким потенциалом? Ммм Улыбающийся    
 
  
 
« Последнее редактирование: Июнь 09, 2016, 00:20 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #38 : Июнь 09, 2016, 00:50 »

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

Для Вас буст - это нечто, что можно изучать и пытаться использовать, и, возможно, не ошибусь - Вас интересует, наверное, больше процесс, чем результат (А как же оно устроено? Как фунциклирует весь этот мир? ага, вот так вот и так вот!) Это в любом случае позитивно характеризует Вас, как ученого-физика, да и для работы Вам же в любом случае приходится что-то программировать Улыбающийся

Для меня же буст - это всего лишь один из инструментов, с помощью которого можно решать определенные задачи. Дело совсем не в "страхе перед новым" - особо нового я в бусте ничего не вижу, скорее наоборот - от некоторых решений прямо-таки веет перфокартами) Я знаю, например, что такое итераторы, и представляю, как они внутри устроены и во что их может "развернуть" компилятор. Хотя, тоже скажу честно  - я тоже не совсем C++ программист (и даже в универе мы его не учили Улыбающийся ) - я в своё время программил разные контроллеры "на ассемблерах", и в мир ООП пришел (стыдно даже сказать) через "мерзкую Дельфи". Сейчас область, в которой я работаю, требует высокой производительности в реальном времени, и постоянного обмена данными с довольно специфичным железом. Там и параллельные вычисления (SSE и прочие AVX), и распознавание образов, и многопроцессорные системы, и 3д-графика... Объёмы кода проектов в этой отрасли - это сотни тысяч и миллионы строк, и само собой, дело не "одного ковбоя в поле", а постоянная командная работа.

Поэтому ввод новой технологии (типа буста) в обиход - это процесс не одного месяца. Для того, чтобы добавить в проект очередную зависимость, требуется чёткое представление о необходимости и оправданности такого решения (причём не только на уровне Software Development). Это значит, что надо переучивать команду, затрачивая на это время и деньги (довольно значительные). Естественно, это выльется в удорожание продуктов для конечных заказчиков, на что "верхний" менеджмент будет смотреть сами понимаете как Улыбающийся И поди объясни заказчику, что "вы понимаете, теперь система стоит на 10000 евро дороже, так как мы решили перейти на другую технологию". Первым же его вопросом будет - "а система стала быстрее работать? мы можем с её помощью добиться больше, чем раньше?"

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

И вот, задав себе все вышеописанные вопросы, я задаю один, обобщающий: "стоит ли оно того или нет?" Что будет для компании более оправданным - внедрение и поддержка универсального, но во всех отношениях "тяжёлого" решения на последующее время или мелкие и недорогие, но быстрые и эффективные "велики"? Ответ не так прост, как кажется...

PS. Лично моё мнение - всякие хорошие вещи рано или поздно скатываются в УГ. C был хорошим языком для своего времени, C++ также был неплох до недавнего времени, но теперешний вектор его развития больше напоминает возвращение в пещеры Грустный Не зря сейчас всякие Rustы с Nimами полезли, как мухоморы, из всех щелей...

Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #39 : Июнь 09, 2016, 12:51 »

Цитировать
И вот, задав себе все вышеописанные вопросы, я задаю один, обобщающий: "стоит ли оно того или нет?" Что будет для компании более оправданным - внедрение и поддержка универсального, но во всех отношениях "тяжёлого" решения на последующее время или мелкие и недорогие, но быстрые и эффективные "велики"? Ответ не так прост, как кажется...
Согласен, да, здесь сложно найти золотую середину)
Здесь ещё один момент - Ваша компания и разработчики буста приследуете несколько разные задачи. Вы пишите конкретно под себя, буст же вынужден быть таким, чтобы дать возможность использывать эту библиотеку в различных проектах. Он просто обязан быть гибким, цена за что - порог вхождения) Но это совершенно нормально.)   
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #40 : Июнь 09, 2016, 12:56 »

Так что же простой пользователь извлекёт из этого? Что я, как конечный пользователь, должен подумать? Для меня этот Ваш ReplaceBlank ровно ни о чём не говорит.. И более того, он решает лишь одну очень частную задачу (в том случае, если пользователь всё же догодается для чего он нужен).. Достаточно слегка изменить условие и никто, кроме, возможно Вас, не станет разбираться, а тем более, переписывать это всё под новую задачу.
Хорошо, допустим в проект пришел новый человек, у него пока опыта с гулькин нос, но вот надо что-то изменить. Найти место где заменяются пробелы - да, в тонне кода это может потребовать времени, но это неизбежно, с этой точки зрения все предложенные варианты одинаковы. А вот разобраться .. в моем коде нормальный студент (второго курса) разберется без проблем. А вот в Вашем - не уверен. Необходимо знание регулярок. Ну это еще полбеды - но вот сколько он будет париться пока догонит как юзать темплейт - хз. Учтите что под рукой у него не будет примерчика с main как здесь. При этом число строк в Вашей и моей реализации практически одинаковы.

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

Ладно, пресловутая "общность". Да, мой код не обладает никакой общностью, да, с ним можно расстаться в любой момент, заменив на что-то другое. И это не плохо, а хорошо Улыбающийся Во-первых мне, т.к. я потратил 5-10 минут и забыл. Продумать действительно общее решение заняло бы у меня куда больше времени, но зачем если это всего лишь одноразовый эпизод? Во-вторых работающему с моим кодом - зачесалось обобщать - на здоровье, а нет - так copy/paste и пару строк подправил. И не надо носик воротить, это нормально. А вот попытки использовать Вашу "обобщенную" вероятно кончатся плачевно. Напр выяснится что менять надо совсем не cap(1), а что-то другое - вот и приплыли. Заметим что др предложенные решения также не стремились ни к какой общности - для нее может и не быть оснований.

Перейдем к бусту. То что там немало идей - никто не спорит. Но вот как-то уж совсем "неласково". Заботы о пользователе буста ноль, упор на концепции. "Умный и так разберется, а дураку и не надо". Жизнь этого тезиса не подтверждает. Время на "разберется" стоит денег. Да, Вы привели нормальный пример xpressive, но почему с гуглы, а не "тыц в доку" (как у нормальных людей). Прочтешь концепты - ну вроде понятно. Но описания методов (по сути хедеры) - так ну его нафиг. Куда там керосин заливать - хз. И очень быстро думается "та ладно, я и так это сделаю за 5 минут". И не надо думать что это "жалкий велик" взамен "действительно глубокого" решения Улыбающийся Это мудрый выбор профессионала (да-да)  Улыбающийся
« Последнее редактирование: Июнь 09, 2016, 12:59 от Igors » Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #41 : Июнь 09, 2016, 14:54 »

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

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

template<typename OutIter, typename BidiIter, typename Formatter>
  OutIter regex_replace(OutIter out, BidiIter begin, BidiIter end,
                        basic_regex< BidiIter > const & re,
                        Formatter const & format,
                        regex_constants::match_flag_type flags = regex_constants::match_default,
                        unspecified = 0);

Вам этот API кажется логичным и гибким? А мне нет. И вот почему:

Проблема 1. Как у нас задается "входной" контейнер? Видно, что двумя итераторами - BidiIter begin, BidiIter end. Первый же вопрос: ЗАЧЕМ? Два различных итератора подразумевают, что человек может взять begin от одного контейнера, а end от другого. Ведь с точки зрения параметров это абсолютно легитимно.

На самом же деле все, что здесь нужно - возможность задать контейнер, как единую сущность (в самом деле, 99% пользователей будут тут писать v.begin(), v.end()). Таким образом мы уменьшаем количество параметров - раз, убираем вероятность передачи неверного параметра - два.

Проблема 2. "Выходные" параметры. Есть OutIter out. И есть OutIter, возвращаемый как результат. Что здесь ожидать программисту? Должен он в качестве параметра передавать out как начало контейнера результата? Наверное, да. Но что тогда он получит как результат функции regex_replace? Конец этого контейнера? ЗАЧЕМ?

Достаточно будет опять же одного параметра в виде контейнера.

Проблема 3. Задать регулярное выражение. basic_regex< BidiIter > const & re. Опять итераторы... ЗАЧЕМ? Для чего регулярку задавать итератором, когда это ничто иное, как строковая константа? Ну ок, должна быть прекомпилирована. Но тогда для этого хватит одного лишь класса, вроде RegExp(const std::string& re);

Проблема 4. Форматтер. Какой у него интерфейс? Из API видно только, что передается некое typename Formatter. Оказывается, что это функтор, а не класс. Получает smatch на вход и возвращает std::string на выход. В примере из гугла внутри функтора создается временная строка, которая преобразуетя и возвращается как КОПИЯ, где, скорей всего, будет еще раз скопирована. Т.е. 3 вызова конструктора строки обеспечены. Производительность, зачем?

А вот как это должно выглядеть по человечески:

void regex_replace(const Container& in, Container& out, const ReClass& re, const Formatter& format, int flags...);

class ReClass
{...
ReClass(const std::string& re)
{
 // here re will be precompiled etc.
}
};

class Formatter
{...
virtual bool DoFormat(Container::const_iterator& from, Container::const_iterator& to, Container::iterator& out)
{
 // нашли текст от from до то в Container in,
 // изменили,
 // положили его в out,
 // вернули true.
 // Если ничего с ним не делали и не меняли - вернули false.
}
};

Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #42 : Июнь 09, 2016, 22:27 »

Цитировать
Хорошо, допустим в проект пришел новый человек, у него пока опыта с гулькин нос, но вот надо что-то изменить.
и далее по списку.. Да, я внимательно прочёл всё нижеследующее, и отчасти понимаю Ваши аргументы.. Но..
Вы действительно полагаете, что затевая какой-либо более-менее крупный проект, который в последующем потребует быстрого расширения и гибкости, нанимая на работу "студентов за еду", которые даже и регулярок толком не знают, Вы ожидаете в недалёком будущем выйграть в себестоимости Вашего поприща? Серьёзно? Этот тезиз реально основан на Вашем личном опыте? Нет, я не заю как на сегоднешней день обстоят дела в действительности, но сейчас для меня это утверждение находится под большим сомнением..   Могу ошибаться, но я пока не увидел реально сильных аргументов в пользу Вашей позиции..

Цитировать
Вам этот API кажется логичным и гибким? А мне нет. И вот почему:

Проблема 1. Как у нас задается "входной" контейнер? Видно, что двумя итераторами - BidiIter begin, BidiIter end. Первый же вопрос: ЗАЧЕМ?
Зачем?! А Вы попробуйте написать такую функцию, чтоб туда можно было впихнуть и C массив и какой-либо контейнер и реализацию от Васи Пупкина..
А Вас не смущает стандартная библиотека алгоритмов?

Цитировать
Проблема 2. "Выходные" параметры. Есть OutIter out. И есть OutIter, возвращаемый как результат. Что здесь ожидать программисту? Должен он в качестве параметра передавать out как начало контейнера результата? Наверное, да. Но что тогда он получит как результат функции regex_replace? Конец этого контейнера? ЗАЧЕМ?
Затем чтоб иметь информацию, где завершился этот алгоритм..  И использовать это условие в более сложных конструкциях..

Цитировать
Проблема 3. Задать регулярное выражение. basic_regex< BidiIter > const & re. Опять итераторы... ЗАЧЕМ?
Я уже отвечал на этот вопрос.. Как Вы себе представляете реализацию регулярки, которая может работать с совершенно разношёрстными последовательностями (QString, std::string и т.д.)?

Цитировать
Проблема 4. Форматтер. Какой у него интерфейс? Из API видно только, что передается некое typename Formatter. Оказывается, что это функтор, а не класс. Получает smatch на вход и возвращает std::string на выход. В примере из гугла внутри функтора создается временная
строка, которая преобразуетя и возвращается как КОПИЯ, где, скорей всего, будет еще раз скопирована. Т.е. 3 вызова конструктора строки обеспечены. Производительность, зачем?
Опять же, сигнатура форматера напрямую зависит от типов данных с которыми Вы работаете. Это может быть QString, std::string  и т.д.. Соответственно и регулярка тоже будет иметь соответствующий тип.. Более того, в качестве форматера может быть передан и класс (все иы знаем про bind). 
Цитировать
где, скорей всего, будет еще раз скопирована. Т.е. 3 вызова конструктора строки обеспечены. Производительность, зачем?
Нет, на самом деле производительность от этого не постродает (если только на самых древних компиляторах).. Сейчас это стандарт де-факто.
 
Цитировать
А вот как это должно выглядеть по человечески:
А как быть тем, кто работает не с std::string? Вы сейчас их права ущемляете Улыбающийся
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #43 : Июнь 10, 2016, 00:55 »

Зачем?! А Вы попробуйте написать такую функцию, чтоб туда можно было впихнуть и C массив и какой-либо контейнер и реализацию от Васи Пупкина..

Зачем заниматься ерундой и скрещивать ежа с носорогом?! Улыбающийся
Функция должна принимать на вход параметры определенного типа, под которые она наиболее оптимально имплементирована.
Конвертирование входных и выходных данных - дело исключительно вызывающей стороны.
Возьмите любую профессиональную библиотеку для, например, обработки изображений.
Там Вы не увидите ни одной функции, принимающей на вход bmp, jpg, png, gif и прочие популярные форматы (не говоря уже про пупкинские).
Вместо этого там будет что-то типа DoFilter(const unsigned char* in, unsigned char* out, int stride,...) и т.д.
Функция просто выполнит свою работу, используя тот тип данных, который для неё является наиболее оптимальным.
КАК Вы передатите ей данные - это Ваша задача. Хочет Пупкин передать MyPupkinContainer? Пусть пишет конвертор. Почему это должно быть проблемой разработчиков библиотеки?

А Вас не смущает стандартная библиотека алгоритмов?

Смущает, очень. И не только меня. Линуса (который Торвальдс), например, тоже смущает.
Процитирую: "You invariably start using the "nice" library features of the language like STL and Boost and other total and utter crap..."

И да, Вы не передадите в STL-функции QString в качестве параметра Улыбающийся

Цитировать
Проблема 3. Задать регулярное выражение. basic_regex< BidiIter > const & re. Опять итераторы... ЗАЧЕМ?
Я уже отвечал на этот вопрос.. Как Вы себе представляете реализацию регулярки, которая может работать с совершенно разношёрстными последовательностями (QString, std::string и т.д.)?

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

Другое дело, если вопрос конвертирования решается на вызывающей стороне. В этом случае Вы точно значете, КАК Вам "скормить" Ваши символы движку. Здесь выиграют все - и регулярка, которая лишится слоя итераторов и построения буфера, и Вы, поскольку получите полный контроль и сможете наиболее эффективно выполнить обмен данными.

Цитировать
где, скорей всего, будет еще раз скопирована. Т.е. 3 вызова конструктора строки обеспечены. Производительность, зачем?
Нет, на самом деле производительность от этого не постродает (если только на самых древних компиляторах).. Сейчас это стандарт де-факто.

Ага, именно поэтому в C++11 добавили Rvalue References Улыбающийся
 
А как быть тем, кто работает не с std::string? Вы сейчас их права ущемляете Улыбающийся

Qt почему-то тоже "не умеет" отображать виджеты GTK Улыбающийся Права гнумовцев ущемлены, Qt sucks? Улыбающийся
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #44 : Июнь 10, 2016, 06:00 »

Проблема 1. Как у нас задается "входной" контейнер? Видно, что двумя итераторами - BidiIter begin, BidiIter end. Первый же вопрос: ЗАЧЕМ? Два различных итератора подразумевают, что человек может взять begin от одного контейнера, а end от другого. Ведь с точки зрения параметров это абсолютно легитимно.

На самом же деле все, что здесь нужно - возможность задать контейнер, как единую сущность (в самом деле, 99% пользователей будут тут писать v.begin(), v.end()). Таким образом мы уменьшаем количество параметров - раз, убираем вероятность передачи неверного параметра - два.
Даже если мы хотим произвести действия над частью контейнера (пусть в году раз) - это легко сделать без итераторов (см здесь). То что эти объявления итераторов громоздки и налипают бесполезным хламом - по-моему более чем очевидно. Но увы, так делают и std и boost - и поэтому "так правильно", остальное "неграмотно"  Плачущий

Но.. Вы действительно полагаете, что затевая какой-либо более-менее крупный проект, который в последующем потребует быстрого расширения и гибкости, нанимая на работу "студентов за еду", которые даже и регулярок толком не знают, Вы ожидаете в недалёком будущем выйграть в себестоимости Вашего поприща? Серьёзно? Этот тезиз реально основан на Вашем личном опыте?
Не скрою, нанимать "студентов за еду" хотелось бы, но ничего не выходит - они не тянут наши задачи. Однако владение бустом и/или std - отнюдь не "залог успеха", эти знания оказываются, ну, скажем, "малополезными". Для нас важнее другие вещи, в первую очередь понимание основ 3D (которые на первый взгляд кажутся очень простыми), да и геометрии вообще, часто нужны математика и физика. Конечно есть и др работа - и с UI (куда ж без него) и с OpenGL (ненавижу эту заразу) и др, но это "решаемо". Поэтому если человек не знает регулярок или "bidirectional iterators" - для нас это не имеет никакого значения  Улыбающийся

Как-то здесь мелькнула удачная фраза типа "если и без какой-то технологии цель легко достигается - то такая технология не очень нужна". Ну в самом деле, не переоцениваете ли Вы те же регулярки? (про буст уж и не заикаюсь Улыбающийся). Вас не смущает что этот "джентльменский набор" знаний у всех удивительно одинаков?
Записан
Страниц: 1 2 [3] 4 5 ... 8   Вверх
  Печать  
 
Перейти в:  


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