Здравствуйте, SGHouse, Вы писали:
SGH>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, Григорьев Вячеслав Владимирович, Вы писали:
ГВВ>>>Статья:
ГВВ>>>Реализация новых парадигм программирования в C++: плюсы и минусыАвтор(ы): Григорьев Вячеслав Владимирович
Дата: 29.12.2011
В статье кратко рассматриваются плюсы и минусы реализации на C++ библиотек / сред, предлагающих разработчику новые парадигмы программирования или новое подмножество языка (Domain Specific Language). В качестве примера обсуждаются реализации функционального программирования в библиотеках boost::lambda и boost::phoenix.
J>>Что-то как-то ни о чем.
SGH>Каждый имеет право на своё мнение. Правда не совсем ясно, почему дальше следует такой набор эмоций, если статья ни о чём.
Ну "обманутые ожидания" и все такое
J>>Насчет отдельно стоящего функтора и прыжков по разным файлам — если функтор попал в отдельный файл, значит, он используется в нескольких местах и с лямбдой по месту будет в результате гораздо больше писанины и copy-paste, чем с вызовом функтора. В моей практике больше 70% воткнутых по месту лямбд в результате преобразовывались в функторы, так как требуемая функциональность требовалась в нескольких местах и поддерживать единообразие гораздо проще, когда у тебя один функтор, а не 20 раз повторенная в разных местах лямбда.
SGH>Этот абзац текста — реакция на какое-то место в статье? Приведите, пожалуйста, ссылку на конкретный абзац статьи. В таком виде, к сожалению, понять Вашу мысль, и как она относится к статье, не удаётся.
ну да, про прыжки между файлами:
Как минимум, это не засоряет пространство имён лишними конструкциями, которые нужны только в одном конкретном месте. Как максимум, делает код более читабельным, так как в реальном исходном тексте функции f1 и work могут находиться далеко друг от друга, и для понимания логики работы придётся воспользоваться текстовым поиском (или различными assistant-средствами IDE) с возможными прыжками по разным файлам.
Если мы продолжаем говорить об однострочных лямбдах, которые только из-за ограничений синтаксиса С++03 выносятся за пределы функции, то их помещают непосредственно перед функцией и никто не будет их засовывать в другой файл, а если засунули — см. мой предыдущий абзац.
J>>Плюс написано о C++0x, но при этом ниже по тексту старое доброе
SGH>С чего Вы это решили? Прочитайте, пожалуйста, внимательно примечание во введении. На всякий случай подскажу — оно начинается со строчки: "Ниже речь пойдёт о версии языка, наиболее широко используемой мировым сообществом до сентября 2011 года — ISO/IEC 14882:1998 / ISO/IEC 14882:2003." Ваши дальнейшие комментарии исходя из этого имеют сомнительную информативность. Тем не менее попробую прокомментировать.
Ок, принято, я невнимательно прочитал этот абзац, решил, что используется C++0x, благо там далее по тексту и С++11-лямбды встречаются.
J>>Насчет сообщений об ошибках — во-первых, в С++0x есть static_assert (BOOST_STATIC_ASSERT), который печатает текстовое сообщение об ошибке, так что можно не возиться с массивами.
J>>Во-вторых, автор, видимо, забыл или не знает о макросах типа BOOST_MPL_ASSERT_MSG, которые печатают вполне читабельные сообщения с кучей звездочек вокруг, так что они замечательно видны в выводе компилятора (а с использованием постпроцессора сообщений компилятора об ошибках вообще все становится замечательно, см. пример ниже), и плюс в них можно запихать типы — крайне полезная вещь в метапрограммировании на типах.
SGH>Макросы такого вида предназначены для авторов метабиблиотек, если те озаботились информативностью возможных ошибок компиляции их библиотек.
Их кто-то запрещает использовать при написании обычных шаблонных функций? Вот прям только метабиблиотеки и все?
SGH>Однако, если Вам предлагается библиотека, в которой широко используется метапрограммирование, но не заложены BOOST_MPL_ASSERT_MSG на все случаи жизни, то очень скоро Вы получите малочитаемое сообщение компилятора.
Естественно, если инструмент не используется, то его полезность нулевая.
SGH>В целом, сравнивать XYZ_ASSERT и диагностику компилятора, на мой взгляд, не корректно.
На всякий случай процитирую себя:
Хотя, естественно, с сообщениями компилятора они не сравнятся, но это гораздо больше, чем "массив или комментарий".
J>>Плюс есть специальные техники (функции-перехватчики), позволяющие сильно уменьшить "простыню", генерируемую компилятором в процессе компиляции некорректного кода.
SGH>Пример, пожалуйста, в студию. Чтобы не быть голословным.
Вот есть у нас здоровенная шаблонная функция, которая имеет смысл только при определенных ограничениях, наложенных на ее аргументы.
Если скормить ей неправильные аргументы, компилятор будет честно компилировать все тело функции, включая функции, которые будут из этой функции вызываться (если они зависят от аргументов шаблона, они будут инстанцированы и скомпилированы), и честно рапортовать обо всех найденных ошибках — в результате легко получить мегабайт ругани компилятора, смысл которой сведется, как Вы правильно отметили в статье, просто к факту "скомпилировалось или нет".
Причем если первой строчкой вставить какой-нть ASSERT c проверкой предиката, то это не спасет — предикат, конечно же, будет проверен, и сообщение будет напечатано, но функция все равно будет компилироваться целиком и выдавать полотенце — компилятор ведь не знает, что мы бы хотели прервать компиляцию функции именно в этом месте.
Правильный подход здесь — сделать однострочную функцию, которая займется исключительно проверкой предиката и на основании проверки вызовет посредством перегрузки через дополнительный параметр типа boost::true_type/false_type либо нормальную рабочую версию функции, в которой все аргументы правильные, либо версию функции, которая будет содержать в себе
только соответствующий ASSERT и комментарий о том, что делать, если такое случилось. В этом случае у компилятора просто физически не будет доступа к некорректному коду, так как он даже не будет инстанцирован.
J>>Далее, автор слегка лукавит, когда говорит, что есть два способа — имена и комментарии, так как комментарий сам по себе никому не виден. Эти способы используются вместе, чтоб по сообщению об ошибке типа
J>>J>>************NON_INTEGRAL_TYPES_ARE_NOT_ALLOWED(void*)************
J>>
J>>можно было прямо в студии сразу же прыгнуть на то место, где она сгенерирована, и прочитать комментарий (в котором могут быть, например, инструкции, как исправить пользовательский код, если это распространенная ошибка).
SGH>Не согласен. Комментарий вполне может использоваться отдельно от специально сгенерированного имени. Важно только, чтобы ошибка компиляции вела на строчку, рядом с которой этот комментарий расположен.
Если сообщение об ошибке в файле библиотеки никак не выделяется среди сотни окружающих ее аналогичных сообщений, то никто в здравом уме не будет прыгать туда и смотреть, что же там сломалось именно на ошибке №49. Так что визуальная сигнализация необходима.
J>>Замечание
J>>J>>Примечание: кстати, выражение (g_a << _1)(“test”) успешно компилируется и выполняется с использованием тестового кода микро-библиотеки, описанной выше.
J>>вообще выглядит издевательством — еще бы оно не работало, если там везде параметры передаются по неконстантной ссылке.
SGH>Пример вырван из контекста.
Где он вырван из контекста? Или мне надо было весь кусок статьи процитировать?
SGH><skip>
SGH>Полагаю, остальные реплики в комментариях не нуждаются. Всего наилучшего.
Т.е. версий библиотек/компиляторов, на которых примеры не работали, не будет?