Здравствуйте, alex_public, Вы писали:
_>А какой в этом смысле? Для тривиальных ("record" в "record") конструкторов логичнее сделать плоскую реализацию (т.е. просто инициализацию всех подряд полей, и своих и предков) — будет и проще и быстрее. А для нетривиальных конструкторов вообще вся эта автогенерация не подходит.
Она не только подходит, но ещё и очень удобна.
На досуге попробуй реализовать наследника System.Exception. Ничего сложного, но на C# тебе придётся написать 4 конструктора. А на немерле их напишет макрос.
WH>>Да вот оказывается, не реализуются. _>Где оказывается то? )
Да вот прямо тут и оказывается.
_>Вот это уже другой разговор. Действительно серьёзные вещи, недоступные на C++.
Как мы выяснили С++у и менее серьёзные вещи недоступны.
_>Кстати, интересно как-нибудь сравнить плюсы и минусы вашей реализации, реализации D,
В D тупое склеивание строк. Никакой гигиены. Короче полный мрак.
_>ну может ещё Rust'a.
Выглядит намного лучше, чем D. Но нужно разбираться.
_>Хотя конечно последние два скорее из одного мира (нативного, позволяющего решать любые задачи), а ваше из другого (из ограниченного мира .net), но в смысле метапрограммирования это наверное не особо принципиально.
От слова совсем.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
K>Да, если юзать спирит, нужно вставить побольше RAM в compile-сервер
Нужно разбивать описание грамматик на части помельче. Что любопытно, MSVC давал в таких местах ворнинг а gcc сегфолт.
И у спирита есть ещё одна фича(?) — тот кто написал вещи типа:
Здравствуйте, alex_public, Вы писали:
_>А что не так со встроенными массивами? )
В том виде, в каком они пришли из C — это вредительство, ИМХО. Ну хотя бы убрать пресловутое "разложение до указателя" хотя бы в 2003 было можно. Например, в неявном виде передавать после указателя на первый элемент длину — примерно так же, как явно делают в C при передаче массива в функцию:
/* C */void foo(int* data, size_t size);
// C++void foo(int data[]) // а на самом деле в функцию передавалось бы то же, что и выше!
{
size_t n = std::array_length(data); // например
// ...
}
_>Насчёт optional... Ну всё же это некий контейнер, так что некие аналогии (скажем с xxx_ptr) имеются. )
Не аргумент. std::vector — тоже контейнер, но он не притворяется указателем ни в каком виде, и нужно слегка постараться, чтобы получить "указатель на элемент".
_>Кстати, например в D добавление в массив реализуется оператором "=+" — всё вполне удобно. )
operator+= или operator=+ ? Вот не нагуглил за 5 минут по теме D operator+= или D operator=+, "Александреску, друг, прости, свой D подальше запусти"(с) Если существует в D operator=+, и он именно используется именно для конкатенации — да на здоровье, вот в Haskell, ЕМНИП, есть оператор конкатенации ++, в Perl конкатенация строк идет через оператор . (точка)
Это я к тому, что оператор "увеличить на значение" и оператор "конкатенация" должны, ИМХО, различаться. "Разные вещи должны выглядеть по-разному, схожие — одинаково".
Кажется, Страуструп писал, что operator<< и operator>> были использованы для ввода/вывода из-за того, что в современной программе практически невозможно будет встретить применение встроенных операторов сдвига. Уже приходилось встречать коллег, которые на вопрос "что делает оператор >>?" бодро отвечали "ввод данных из потока"
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
K>Сейчас кто-нибудь придет и скажет, какой это красивый и выразительный код
Насчет красивого хз, но все понятно.
Непонятно только, зачем там кавычка, если терминатор — '0x1F').
Плюс, чтобы вычитать символы из множества, нет нужды каждый символ оборачивать в bs::ch_p. Так что весь крокодил bs::anychar_p — bs::ch_p( 0x1F ) — bs::ch_p( '"' ) превращается в коротенький ~bs::chset("\x1F\"").
Плюс для чтения строчки, ограниченной всякими '0x1F', есть специальный парсер confix_p.
Т.е. парсер для строчки, ограниченной '\x1F', вместо всего крокодила выше, будет записываться как:
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, kurchatov, Вы писали:
K>>jazzer, расскажите нам, как банки ценят разработчиков со знанием boost.
J>Очень ценят.
Здравствуйте, WolfHound, Вы писали:
WH>Она не только подходит, но ещё и очень удобна. WH>На досуге попробуй реализовать наследника System.Exception. Ничего сложного, но на C# тебе придётся написать 4 конструктора. А на немерле их напишет макрос.
Ну так то, что в C# всё плохо с МП ты можешь меня не убеждать... )))
WH>Да вот прямо тут и оказывается.
Пока по нашей дискуссии ничего не оказывается. Хота в реальности действительно всё весьма слабо.
_>>Кстати, интересно как-нибудь сравнить плюсы и минусы вашей реализации, реализации D, WH>В D тупое склеивание строк. Никакой гигиены. Короче полный мрак.
Не не не. То, что все вспоминают функцию mixin из D, совершенно не означает, что она является единственным инструментом МП там. Скорее наоборот, это инструмент для особых случаев, которые не решаются по нормальному. А обычно там применяются шаблоны, только доведённые до ума (полноценные вычисления во время компиляции, в том числе и со строками).
_>>ну может ещё Rust'a. WH>Выглядит намного лучше, чем D. Но нужно разбираться.
Я пока вообще не в курсе. Но мне показывали примеры с проверкой sql синтаксиса при компиляции (не в кривом варианте типа отображения на функции языка, как в linq или даже в C++ библиотеках, по нормальному) — это впечатляет.
Здравствуйте, slava_phirsov, Вы писали:
_>>А что не так со встроенными массивами? ) _>В том виде, в каком они пришли из C — это вредительство, ИМХО. Ну хотя бы убрать пресловутое "разложение до указателя" хотя бы в 2003 было можно. Например, в неявном виде передавать после указателя на первый элемент длину — примерно так же, как явно делают в C при передаче массива в функцию:
Это будет нарушение принципов C/C++ — лишние накладные расходы. К тому же зачем оно, если у нас имеется std::array? )
_>>Насчёт optional... Ну всё же это некий контейнер, так что некие аналогии (скажем с xxx_ptr) имеются. ) _>Не аргумент. std::vector — тоже контейнер, но он не притворяется указателем ни в каком виде, и нужно слегка постараться, чтобы получить "указатель на элемент".
Не, это другой контейнер, хранящий много экземпляров. А у optional аналогия как раз ближе к какому-нибудь unique_ptr или future. )
_>>Кстати, например в D добавление в массив реализуется оператором "=+" — всё вполне удобно. ) _>operator+= или operator=+ ? Вот не нагуглил за 5 минут по теме D operator+= или D operator=+, "Александреску, друг, прости, свой D подальше запусти"(с) Если существует в D operator=+, и он именно используется именно для конкатенации — да на здоровье, вот в Haskell, ЕМНИП, есть оператор конкатенации ++, в Perl конкатенация строк идет через оператор . (точка)
Ой, это я ерунду сказал. ))) На самом деле конечно же оператор "~=" добавляет что-то в новый. В то время как оператор "~" реализует именно создание нового массива состоящего из старого, плюс новый элемент.
Здравствуйте, TimurSPB, Вы писали:
EP>>Тут даже не нужно знать Boost.Spirit, чтобы понять что происходит TSP>А потом туда добавляются всякие правила для комментариев, потом ещё что то. И всё превращается в тяжело поддерживаемую простыню.
Зачем в простыню-то? Расстилать простыни можно на любом языке.
TSP>У меня доходило до того, что компилятор падал на этапе компиляции.
Выше была претензия про понятность такой грамматики — я показал конкретный пример, который на мой взгляд понятен даже человеку не знакомому с Boost.Spirit.
То что у него есть какие-то другие недостатки — я с этим не спорю. Время компиляции — один из них, хотя часто и не является show stopper'ом.
Кстати говоря, использование новых языковых фич позволит ему компилироваться быстрее, например: http://boost-spirit.com/home/2013/02/23/spirit-x3-on-github/
Здравствуйте, alex_public, Вы писали:
_>Это будет нарушение принципов C/C++ — лишние накладные расходы. К тому же зачем оно, если у нас имеется std::array? )
А неявная передача указателя this — не лишние накладные расходы? В ту пору std::array не было, а с std::vector была небольшая проблемка — списков инициализации еще не придумали, и заполнять содержимое контейнера приходилось руками:
string items[] = {"I'v", "been", "expecting", "you", ",", "mr", "Stroustrup"};
call(items); // Опасно, ведь call(), увы, не знает размер переданного массива
// А если бы знал - было бы безопасно!
_>Не, это другой контейнер, хранящий много экземпляров. А у optional аналогия как раз ближе к какому-нибудь unique_ptr или future. )
Не согласен, на том и остановимся
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Здравствуйте, alex_public, Вы писали:
WH>>Она не только подходит, но ещё и очень удобна. WH>>На досуге попробуй реализовать наследника System.Exception. Ничего сложного, но на C# тебе придётся написать 4 конструктора. А на немерле их напишет макрос. _>Ну так то, что в C# всё плохо с МП ты можешь меня не убеждать... )))
Ты уходишь от темы про нужность нетривиальных конструкторов.
WH>>Да вот прямо тут и оказывается. _>Пока по нашей дискуссии ничего не оказывается. Хота в реальности действительно всё весьма слабо.
Ну как же?
Дали вам две задачки. Обе не решены.
Мне про метапрограммирование на С++ рассказывать не нужно. Я про него всё знаю. По тому и могу легко задачки неберучки придумывать.
_>Не не не. То, что все вспоминают функцию mixin из D, совершенно не означает, что она является единственным инструментом МП там. Скорее наоборот, это инструмент для особых случаев, которые не решаются по нормальному. А обычно там применяются шаблоны, только доведённые до ума (полноценные вычисления во время компиляции, в том числе и со строками).
Ну, ты дай ссылку на "то". Чтобы я опять что-то "не то" не подумал.
_>Я пока вообще не в курсе. Но мне показывали примеры с проверкой sql синтаксиса при компиляции (не в кривом варианте типа отображения на функции языка, как в linq или даже в C++ библиотеках, по нормальному) — это впечатляет.
Ссылку?
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, slava_phirsov, Вы писали:
_>>Это будет нарушение принципов C/C++ — лишние накладные расходы. К тому же зачем оно, если у нас имеется std::array? ) _>А неявная передача указателя this — не лишние накладные расходы?
Так оно же не в дополнение, а вместо. )
_>В ту пору std::array не было, а с std::vector была небольшая проблемка — списков инициализации еще не придумали, и заполнять содержимое контейнера приходилось руками: _>... _>Сравни с: _>...
Нуу, если очень нужна безопасность и это у нас C++, то можно было сделать банально call<N>(items);
Но в любом случае в современном C++ это уже всё давно не актуально. )
Здравствуйте, WolfHound, Вы писали:
WH>Ты уходишь от темы про нужность нетривиальных конструкторов.
Естественно они нужны. Но как это пересекается с темой автоматической генерации тривиальных конструкторов...
WH>Ну как же? WH>Дали вам две задачки. Обе не решены.
Я вижу в основном мелкие придирки)
WH>Мне про метапрограммирование на С++ рассказывать не нужно. Я про него всё знаю. По тому и могу легко задачки неберучки придумывать.
Вообще то судя по сегодняшнему обсуждению, про C++ ты на самом деле не совсем в курсе. Во всяком случае про современный. Но при этом тезис о слабости метапрограммирования в C++ (естественно в сравнение с D/Rust/Nemerle, а не каким-нибудь C#, где вообще ничего нет) я оспаривать не собираюсь. Причём я об этом писал тут уже не раз.
WH>Ну, ты дай ссылку на "то". Чтобы я опять что-то "не то" не подумал.
А функция mixin (http://dlang.org/mixin.html) живёт по сути отдельно от всего этого и типа реализует всё что угодно, что не укладывается в варианты выше.
_>>Я пока вообще не в курсе. Но мне показывали примеры с проверкой sql синтаксиса при компиляции (не в кривом варианте типа отображения на функции языка, как в linq или даже в C++ библиотеках, по нормальному) — это впечатляет. WH>Ссылку?
(вообще, для такого простого парсера достаточно коротенького регэкспа ([^\x1F"]*)\x1F?, так что я предполагаю, что это часть какого-то большого парсера)
CC>На деле оказывается проще сразу расстрелять агитирующих за спирит и изначально писать на чёи либо другом.
TSP>>тот становится незаменим при поддержки кода. Если такой бусто-спиритист уходит из команды, то проще переписать.
CC>На деле оказывается проще сразу расстрелять агитирующих за спирит и изначально писать на чёи либо другом.
Так ты предложи внятную замену спириту. А то много кому не нравится буст и спирит в частности, но ничего внятного на замену предложить не могут.
И вот здесь, внезапно, оказывается так, что любой человек, который способен написать внятный парсер, становится незаменимым при поддержке кода. А переписывать — так принято у программитов. Заодно это еще и хороший способ разобраться с теми же парсерами.
Здравствуйте, Ikemefula, Вы писали:
CC>>На деле оказывается проще сразу расстрелять агитирующих за спирит и изначально писать на чёи либо другом.
I>Так ты предложи внятную замену спириту. А то много кому не нравится буст и спирит в частности, но ничего внятного на замену предложить не могут.
<раз уж мы все равно в СВ />
Ну как не могут? Точнее, так — думают что могут — героически переписывают это на scanf (заодно и "перфоманс поднимут" (с), ага =)
А потом любой случайно залетевший дятелпробел в данных ломает их "быстренько написанный" код на тысчонку другую строк — к такой-то матери. Потом, поскольку эти тонны кило легко усвояемой лапши на самом деле никак не перевариваются — рядом пишется еше сотни такой же. В общем нет предела совершенству. Наступает этакое экологическое равновесие — круговорот говна в природе.