Достала избыточность С++

imageПривет Хабр,
Меня вводит в ступор С++. Вот просто, зависаю над монитором, смотрю в окно, попиваю чай… И начинаю жалеть за бесценно проведенные годы за изучением стандарта С++, попытками написать свой фронт-энд компилер. Эти мудреные книжки С++ In Depth. Как же я негодовал, когда не понимал кода из книги Александреску. Как записывал все постулаты Страуструпа и иже с ними. Зачем? Вот спрашиваю себя, зачем я теперь все это знаю. Более, я хочу сказать, что этот язык нещаден для гуру, не с медицинской, не с экономической точки зрения! Он не оправдывает усилий, вложенных в его изучение — раз. На практике, он экономически не выгоден — два. И нервные клетки подтвердят, что сопровождать чужой плюснутый код — бывает опасно для здоровья -три. Пусть тут будут рандомно разбросаны метафоры, пишу как есть, из опыта.


Вот, например, из-за зубренных постулатов: объекты в методы передавать как константные ссылки.
Да, я пока пишу
Status DetectionManager::GetDetectionStatus(const FileScanTask &fileTask) const {
    m_detector.GetDetectionStatus(fileTask);
}


Забываю про задачу как таковую. А в голове крутится: надо чтоб не было класса Бога, поэтому делегируем обязательства, надо передавать объект по костантной ссылке, метод тоже должен быть const, а вдруг нам нужно будет изменять что-то… ммм… тогда объявлю m_detector как mutable. Но тогда моего коллегу джуниора может это смутить… что-же делать.
Создать второй метод? Так, члены должны объявляться с префиксом 'm_', чтобы не было. А может стоит еще обозначить что метод генерирует исключения? Добавить throw к нему?
Будет яснее, но опять же джуниор…
Это простой пример, где решение задачи, напрочь смывается из памяти этими-всеми «плохой тон программирования».

Вот еще подборочка, для любителей хорошего тона:
С членами классов работать через set/get методы. Даже если у вас класс Exception с одним членом reason, нам нужно, по правилам хорошего тона, объявить конструктор, метод Get, метод Get const, можно и Get const volatile, а вдруг пригодиться? А как насчет пойти дальше, сделать все методы приватными и добавлять по friend'у, кто их использует? Ах да, не забудь про виртуальный деструктор!

Далее в порядке бреда от малого до великого:
— Никаких goto. Лучше do { break; } while(0); От этого суть глобально меняется.
— Параметры макросов в скобках. А вообще макросы нельзя употреблять! Это же нарушает типизацию.
— Никаких указателей, даже если очень хочеться. Только умные, с 4-мя шаблонными параметрами.
— Никаких глобальных переменных. Низя!

Впрочем, стоит почитать Скота Мейрса, Александреску, наших авторов, для продолжения списка. Просто лень тянуться на полку… Я не против знаний, я против их переизбытка применительно к задаче.

Еще из эстетствующего:
— Не должно быть больше 4 вложенных конструкций. А если очень надо? — Разделяй на функции. Причем протитип в хэдер, реализацию рядом с основной функцией.
— Множественное наследование — плохо. Зато виртуальное наследование, спецификаторы
доступа при наследовании, и какие они будут в наследуемом классе — надобно знать. Очень нужная вещь… на собеседованиях
— reinterpret_cast, static_cast, const_cast. Почему нет private_to_public_in_case_exception_cast?

Далее, такие записи:
— Это мы получаем при поиске в map'е. Детям нельзя такое преподавать.
typedef typename _STD tr1::conditional<
        _STD tr1::is_same<key_type, value_type>::value,
        const_iterator,
        _Tree_iterator<_Mybase> >::type iterator;


— А как вам такой пул потоков. Это при том, что задать нотификатор о завершении потока, или приостановить поток — проблемно. В том же WinApi, делается в 2 функции. А тут мета политики! Причем в TODO еще одна на подходе. Забыли про случай, когда шнур из розетки вылетает.
template <
    typename Task                                   = task_func,
    template <typename> class SchedulingPolicy      = fifo_scheduler,
    template <typename> class SizePolicy            = static_size,
    template <typename> class SizePolicyController  = resize_controller,
    template <typename> class ShutdownPolicy        = wait_for_all_tasks
  > 
  class thread_pool


Скучно стало в академ кругах, и ай да еще:
Тут тебе и rvalue-ссылки &&, и constexpr, и шаблоны с переменным количеством параметров. Без этого ж не кодилось.
Полный список здесь.
Кто это все осилит? Это несколько лет непрерывных проб и ошибок, пока терпения хватит. Из C++ 0x только auto и лямбды в параметрах STL-алгоритмов, на практике пригодились.

Все остальное — это переизбыток и многословность!

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

Резюмируя. Топик об избыточности моментов языка. И от этого большей сложности. Например, хочешь использовать списки? Будь добр, пойми, что такое шаблоны, область видимости, мета-программирование отчасти, и так далее, цепной реакцией. Иначе, не зная как работает твой код — становишься проблемой всего проекта.

Удачи!
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 534

    +79
    Долой программирование!)
      +25
      Или: Даёшь ассемблер в массы! :)
      • UFO just landed and posted this here
          +1
          Правильно Роботов на разработку!
        +1
        Серьезному языку — серьезные задачи: драйверы и другое низкоуровневое ПО, критичное к производительности ПО и так далее.
        Простую утилиту(надеюсь) на плюсах писать никто не будет.

        А мощный универсальный простой язык — это(пока) из области фантастики.
          +53
          Ну, так… для этого есть чистый C, а автор пишет про особенности плюсов, которые его бесят, они производительность не поднимают.
            +8
            Простая истина: не нравится — не ешь. Т.е. бесят — не используй.
            Как будто автора силком заставляют использовать все возможные фичи языка.

            Кстати, вопрос насчёт
            Даже если у вас класс Exception с одним членом reason, нам нужно, по правилам хорошего тона, объявить конструктор, метод Get, метод Get const, можно и Get const volatile, а вдруг пригодится?

            А при каких условиях может вообще появиться не константный Get?
              +3
              Например, если Get выполняет отложенную инициализацию при первом обращении. Можно, конечно, mutable везде напихать, но это будет ещё ужаснее.
                +2
                >Например, если Get выполняет отложенную инициализацию при первом обращении.

                Тогда это уже далеко не тупой геттер небольшого класса с одним членом (как в оригинале у автора), а более сложная модель, для которой плюс-минус метод-другой роли не играет.
                0
                А при каких условиях может вообще появиться не константный Get?

                Если используешь стороннюю библиотеку или просто модуль, написанный кем-то другим, кто не использует const'ы.

                не нравится — не ешь

                Согласен.
                От себя маленькое добавление. Лично мне нравится избыточность богатство возможностей, предоставляемое этим языком. C++ имеет недостатки, но надо понимать, что C++ создан из компромиссов между требованиями к производительности, совместимости, переносимости, идеологией zero-overhead и т.д. В C++ ничего не добавлялось просто так. Устраняя избыточность, обязательно будешь жертвовать чем-либо (обычно производительностью).

                В любом случае, С++ может быть таким, каким захочешь, ведь никто не запрещает использовать «неизбыточный» C++ в виде фреймворков, таких как Qt. «you can be my princess, or you can be my whore»

                Каждая новая фича сопровождается подробным объяснением, для чего она нужна. И, опять-таки, zero-overhead позволяет не знать об этой фиче до тех пор пока не наткнешься на проблему, которая с помощью этой «избыточной» фичи решается тривиально.
                0
                Не всегда. Например, на темплейтах довольно легко можно писать zero-copy, т.е. прозрачно передавать указатели вместо данных и индексы подстрок вместо самих подстрок. На чистом C это крайне тяжело.
                • UFO just landed and posted this here
                    0
                    На С прозрачно — нельзя. В С все явно нужно писать.
                    Это обратная сторона полного контроля над генерируемым кодом.
                    • UFO just landed and posted this here
                        0
                        Все-таки на данном этапе развития IDE все перечисленное не является проблемой — одно движение мышкой и вы знаете что стоит за именем в коде.

                        А вот то что в С почти все проверки возложены на программиста приводит к тому что в большом проекте на С можно намного проще, чем в С++, словить всякие утечки памяти и прочие радости.

                        Не бывает идеальных решений: в одном месте делаем проще, в другом становится сложнее.
                        • UFO just landed and posted this here
                          +3
                          А sqrt(2); может форматировать диск, как страшно жить.
                          На мой взгляд, это достоинство — код получается недвусмысленный, а это самый важное условие простоты

                          Простоты чего? Когда нормальные абстракции невозможны, это не простота получается, а попытки высмотреть то, что хотел сказать программист, за кучей непонятных конструкций. Например, вернуть массив из функции — проблема, ведь кто-то должен выделять память, и в итоге функция обрастает вокруг себя выделениями буферов. Это приводит к тому, что можно забыть писать просто f(g(x)), нужно выделять буферы, использовать tmp-переменые и т. п. Зато все кишки на виду. В этом отношении ассемблер еще проще.

                          Что делает этот код?
                          list_for_each(pos, &mylist.list){
                          tmp= list_entry(pos, struct kool_list, list);
                          printf(«to= %d from= %d\n», tmp->to, tmp->from);
                          }

                          Неизвестно, ведь list_for_each и list_entry — макросы препроцессора, который в С активно используется именно потому что больше нечего использовать, а прятать копипасту нужно, и это я пропустил ту часть, которая выделяет под это все память.
                            +6
                            Ещё забыли про повсеместно используемый void** :)
                              +1
                              И вы правы, и ваш оппонент прав. Чтобы использовать Си в новом проекте нужны очень веские причины, о и чтобы пользоваться всей мощью Си++ нужны они же.
                      0
                      Смотря производительность чего. Производительность программиста таки поднимают, так как чем высокоуровневей язык, тем проще делать сложное.
                      +7
                      Слава Богу, но драйвера, ПО для встраиваемых систем и прочее низкоуровневое пишут на С или Embedded C++.
                        +2
                        Я простые утилиты пишу на C++. Мне он нравится, ничего не могу с собой поделать. Как правильно заметили ниже, никто не заставляет использовать все фичи.

                        Кстати, некоторые из перечисленных «камни преткновения» легко можно набросать и в «огороды» всяких там Джав и СиШлаков.
                          0
                          Пардон, правильно заметили выше :)
                        • UFO just landed and posted this here
                            +2
                            На выходных контест был, и ярый адепт С++ в лице меня писал игру на (о боги!) Java о_О Прикинь.
                            Так знаешь, через пару часов Java мне показалась не таким уж плохим языком.
                            • UFO just landed and posted this here
                                +4
                                Верно то, что это не проблема языка.
                                  –1
                                  Дело, конечно, Ваше. Но! Применительно к лаконичности языка, Java превосходит С++, а C# превосходит Java, а Ruby… ну т.д. Возможно, авторы C++ грезили всемирной революцией и поспевая за развитием Java начали искать ему применение всё в большем количестве областей, добавляя к нему новые конструкции. Возможно! Но ведь получился уродец на костылях. Он, конечно, ходит. Но как?!
                                    +2
                                    Применительно к лаконичности языка, Java превосходит С++

                                    Очень спорно.
                                      0
                                      Потому и спорим). Соглашусь, такие вещи надо обсуждать в контексте. Каждый конкретный случай. Сложность такой задачи O(N+1)! Ну, давайте возьмём какое-то приближение.
                                      –3
                                      c# с кучей синтаксического сахара превосходит Java в лакончиности? О_о
                                        +3
                                        Именно превосходит. Одно слово — Лямбды.
                                      0
                                      Спринг и хибер уж года три можно аннотациями конфигурить.
                                      –1
                                      И все бы ничего, если бы не потенциальная тормознутость Java по сравнению с C++.
                                      А разработка-то на ней однозначно легче. По крайней мере можно не думать о бесконечных амперсандах и звездочках.
                                        –5
                                        Ну даже если 10мс вместо 2мс. Вы так говорите об этом, как будто это что-то плохое)
                                          +7
                                          Внезапно: 1000 раз по 10 мс — здравствуйте, 10 секунд!
                                            0
                                            А если их не будет? Всё это преждевременно. Каждая задача требует своего решения.
                                              0
                                              Вот в том то и дело — есть задачи в которых заведомо известно что будут тысячи обращений.
                                                +2
                                                >А если их не будет?

                                                А если будут?

                                                >Всё это преждевременно.

                                                А когда будет «не преждевременно»? Когда проект будет близок к завершению и вдруг «внезапно» выяснится, что Java его банально не тянет?

                                                Живой пример из жизни: жила себе здравствовала компания Nortel. Вы о ней, наверное, слышали: именно её патенты сейчас всё никак не могут поделить Гугл, Яббл и Микрософт. Но в своё время она была известна не только патентами, но и отличными решениями для SIP-телефонии (как софтовыми, так и хардварными).
                                                И писали они как-то софтовый SIP-клиент, и всё было хорошо… пока не обнаружилось, что на реальных задачах Java (на которой он был написан) тупо не справляется, и экономически выгоднее выкинуть текущий проект и переписать всё на C++. Это реальный факт из жизни (я в своё время сам немного «приложился» к этому портированию).

                                                >Каждая задача требует своего решения.

                                                В рамочку и на стену :)
                                                  0
                                                  Когда-то мы на ещё одном контесте решили использовать Java. Там было что-то типа игры, и на каждом такте этой игры (то есть где-то раз в 50 мс) нам нужно было делать поиск в ширину по очень большому полю. Мы страшно боялись, что не будем успевать делать полноценный BFS, поэтому начали придумывать всякие оптимизации. Сперва это не помогало. Но в конце концов выяснилось, что основная проблема была в медленном вводе-выводе :) Переписав его мы не только производили полноценный поиск в ширину, но ещё и куча времени оставалась. Так что, как бы мне ни не хотелось признавать это, Java не такая уж медленная иногда.
                                                    +1
                                                    >Java не такая уж медленная иногда

                                                    А я разве говорю, что она «всегда и везде тормозная»? :)

                                                    Я говорю о том, что нужно думать перед тем, как выбирать инструмент, а то соображения «ну даже если 10мс вместо 2мс. Вы так говорите об этом, как будто это что-то плохое» и «рано об этом думать, всё это преждевременно» вполне могут завести в полнейшую жопу.
                                                      0
                                                      > Я говорю о том, что нужно думать перед тем, как выбирать инструмент

                                                      Ну так я с этим всецело согласен :)
                                                        0
                                                        Вы может меня не поняли, но я считаю, что надо ДУМАТЬ перед тем как делать. Надо наибыстрейшее вычисление выбираем наибыстрейший язык, надо наибыстрейшее разрабатывание выбираем опять же нужный язык. Вообще у меня склыдывается мнение, что говорим мы об одном и том же, но с разных сторон.
                                                0
                                                Suddenly, 1мс и все оптимизации идут лесом)
                                                0
                                                Все всегда зависит от задачи. Конечно же для некоторых задач это некритично. А вот сложная математика должна работать быстро. И вот для нее выбирают C или плюсы.
                                                  0
                                                  Знаете, а у нас к некоторым вещам есть требование на скорость отклика… и 10 вместо 2 мс…

                                                  Но для простоты юзают джаву — да. Пользователи негодуют.
                                                  0
                                                  Сравнивать С++ с Java не резон. Я бы начал сравнивать C# и Java как более похожие, но С++ vs Java — это холивар.
                                                    0
                                                    Сильные холивары обычно когда сильно похожие ) Слабо представляю себе холивар на тему что лучше для разработки сайтов — пхп или асм ))
                                                      0
                                                      Все зависит от задачи. Есть вещи, которые лучше напишутся и лучше будут работать не джаве, есть на плюсах. Надо уметь оценивать, какого рода задача стоит сейчас.
                                            –13
                                            Вау! Интересная статья. Я давненько таких не видел. Спасибо. +1 и в избранное.
                                              –5
                                              Ну так не нравится — не ешьте, вас не заставляет никто.
                                              • UFO just landed and posted this here
                                                  +8
                                                  Зачастую, читая топики на хабре, я кажусь себе юродивым и неполноценным, из-за того что не люблю такой мощный олдскульный язык, ах ах ах. Но потом вспоминаю про c#, в котором не надо задумываться о тех вещах, над которыми заставляют корпеть плюсы, и мне становится легче.
                                                  • UFO just landed and posted this here
                                                      +4
                                                      Управление памятью? :-/
                                                        +1
                                                        Чё-то я особого дискомфорта в С++ по этому поводу не испытываю. Когда-никогда приходится и правда задуматься, а как бы получше реализовать управление памятью в том или ином месте?
                                                        • UFO just landed and posted this here
                                                            –1
                                                            Из того, что сборщик на счетчике ссылок медленнее сборщика на mark and sweep не следует, что счетчик для какой-либо переменной медленнее.
                                                            Использование shared_ptr для всего вообще действительно все затормозит по сравнению с GC, потому что «всё вообще» обычно часто присваивается и копируется, но.
                                                            Если разыменования указателя происходят чаще копирования и присваивания, умные указатели быстрее, потому что такое разыменование ничем от разыменования обыкновенного указателя не отличается. Для persistent tree так оно и есть, иначе зачем его вообще делать, если оно перестраивается чаще, чем обходится.
                                                            Медленность С++ по сравнению управляемыми языками в искусственных тестах обычно упирается в тормознутый основной аллокатор, хотя объясняют это именно умными оказателями. Об действительно нужно задумываться, но с бустом не так страшно.
                                                            • UFO just landed and posted this here
                                                                –1
                                                                GC, в отличии от этого, не трогает «мертвые» объекты вообще

                                                                Как же он мусор из кучи собирает? Если он их сразу не трогает (не помечает как свободные), значит он трогает их потом.
                                                                В случае умных указателей оверхед на удаление велик при стандартном аллокаторе, который выдает память любого размера. В случае пула, который выдает одинаковые объекты, удалять действительно нужно все, но это удаление будет сводиться к той же пометке свободных блоков.
                                                                Если создавать дерево из пустого от листьев к корню, то удалений не будет вообще, обычно они так и разворачиваются. Если делать как-то по-другому, не понятно, почему счетчик будет медленнее.
                                                                • UFO just landed and posted this here
                                                                    –1
                                                                    Собирает очень просто — вычисляет граф «живых» объектов, затем перемещает живые объекты так, что-бы они лежали последовательно друг за другом, уплотняя кучу.

                                                                    Ну т.е. вместо установки false для блока внутри пула (который тут же будет повторно использоваться), двигает объекты по куче, которые могут быть весьма толстыми? Не самая приятная вещь для миллиона объектов, постоянно придется из кэша лазить в память, что совсем небыстро.
                                                                    В случае умных указателей все равно нужно выполнить код удаления для каждого объекта, даже если используется какая либо хитрая стратегия управления памятью.

                                                                    Декремент счетчика, проверка на ноль, пул_аллокатор.занят[смещение_указателя/размер]=false. Все инлайнится и делается не выходя из кэша.
                                                                    речь шла о персистентном дереве, там при каждой вставке элемента в дерево будет происходить копирование log N узлов дерева и удаление log N узлов дерева (если конечно мы не сохраняем все старые версии дерева).

                                                                    У персистентного дерева добавление к корню бесплатно (в том числе от корню существующего дерева), и его очень удобно конструировать и повторно использовать таким образом. Частая замена, которая вызывает работу GC, какой-то странный вариант для языка с присваиваниями даже в многопоточной среде даже если GC охота использовать.
                                                                    • UFO just landed and posted this here
                                                                        –1
                                                                        Для толстых объектов есть отдельная куча. По факту это работает быстро, он ведь не делает это для всех объектов сразу

                                                                        И для миллиона толстых объектов отдельная? По факту я знаю как это работает.
                                                                        Эти счетчики ведь будут в памяти произвольным образом распределены. Да и декремент нужно делать атомарно, а это неслабые накладные расходы.

                                                                        Счетчик лежит рядом с указателем, к которому мы и так постоянно обращаемся для разыменования. Разыменование идет в пул, в котором тоже все относительно рядом. И профайлером можно посмотреть, в отличие от попыток угадать, что там GC себе надумает.
                                                                        Атомарный декремент как раз и вызовет промах, достаточно слабо для уровня управляемых языков, где навскидку все косвенное.
                                                                        Новый элемент не добавляется к корню, там каждый раз создается новое дерево, при этом старое никуда не девается.

                                                                        Конечно не девается, новый элемент начинает указывать на корень старого дерева, поэтому его так быстро создать рекурсивной функцией и пересобирать, зная, что большая часть элементов останется на месте. Иначе толку от него — гордиться отсутствием присваивания.
                                                                        • UFO just landed and posted this here
                                                        • UFO just landed and posted this here
                                                            0
                                                            «Уже давно» — это сколько лет?
                                                              +3
                                                              17 лет, с момента стандартизации STL в 1994-м году.
                                                                0
                                                                В 1995-6 упоминания о нем не видел в продававшихся тогда книгах :(
                                                                  +1
                                                                  shared_ptr и не было до буста. Но вместе с STL появился auto_ptr (точнее, он появился раньше в библиотеках SGI но не суть), который как бы тоже смарт-указатель.
                                                                    +2
                                                                    По поводу shared_ptr ответили ниже, хочу сказать о другом.
                                                                    Книги по С++ из 90-х — это ужас. Как и 80% книг, которые продаются сейчас, которые переиздаются без именений по многу лет. 40% страниц описывается С (с динамическими массивами на указателях), еще 40% — основы синтаксиса ООП, и махонькая глава, посвященная STL, что мол есть вектор, а зачем он есть — не понятно.
                                                                    В итоге и считается нормой, что массивы в прикладном коде передаются из функции по указателям (с соответствующим выделением памяти вне функции) вместо того, чтобы возвращать std::vector через return и много других подобных примеров.
                                                                    Потом человек читает Александреску и его бросает в другую крайность. Писать на C++ так же, как на C# — без маблонной магии, но и без сишных открытых выделений памяти и велосипедов, почему-то западло.
                                                                      +2
                                                                      Ну в принципе да, примерно такого уровня и читал книги. Ну и F1 :)
                                                                • UFO just landed and posted this here
                                                                +21
                                                                Да причем здесь управление памятью. Код читабельней!

                                                                Нет всяких закорючек, спец. символов, раздвоения методов на декларацию/имплементацию.
                                                                Сравните:
                                                                Status DetectionManager::GetDetectionStatus(const FileScanTask &fileTask) const {
                                                                    m_detector.GetDetectionStatus(fileTask);
                                                                }

                                                                public Status GetDetectionStatus(FileScanTask fileTask)
                                                                {
                                                                    return _detector.GetDetectionStatus(fileTask);
                                                                }
                                                                

                                                                Насколько второй код визуально чище и понятней. И писать его проще, не надо про думать про &, const, :: и т.д. А вы всё про память…
                                                                  –8
                                                                  Что из этого читабельнее еще большой вопрос. Это очень субъективная вещь — мне лично сложно _не_ думать о том где параметр передается по ссылке, где по значению, какой здесь класс и неймспейс и прочее прочее. Думаю я не один такой.
                                                                    0
                                                                    Да ну пишите всё в хедерах, ради бога… Не будет Вам никаких ::
                                                                    А вот const после метода очень даже не лишний — сразу понятно, есть ли у метода… кхм… «побочные эффекты».
                                                                      +5
                                                                      Именно, что хедеров нет вообще. Зачем они?
                                                                        +4
                                                                        Потому что такая модель комплияции :) Ну и это просто удобно — интерфейс в одном месте, реализация в другом. Хочешь окинуть взглядом класс — посмотрел хедер. Хочешь покопаться в деталях, полез в реализацию. Как-то это, естественнее что-ли. Когда после С / С++ начинаешь писать на языках где нет хедеров начинается страшная ломка. Так что это, имхо, дело привычки.
                                                                          0
                                                                          Само собой. Я просто лезу в IMyInterface.cs для осмотра интерфейса :)

                                                                          А для классов, как-то не страдаю из-за отсутствия хедера. Так же дело привычки.
                                                                            +9
                                                                            Если нужно окинуть взглядом класс, можно хоткеем скрыть все, кроме имен методов. Да здравствует IDE 21-ого века. :)
                                                                              0
                                                                              против таких ломок есть приёмок: docstring на уровне синтаксиса и perldoc/pydoc.

                                                                              почти что мечта Д. Кнута.
                                                                            +1
                                                                            Если писать все в хедерах, то в больших проектах, это чревато бОльшим временем перекомпиляции при изменение одного хедера, а особенно, если он часто используется. А const действительно полезен имхо, считаю его отсутствие серьезным недостатком C#, не учитывая еще того, что в плюсах можно отловить много ошибок еще во время компиляции, чего сделать непросто в C#
                                                                              –3
                                                                              В плюсах на const надеятся нельзя. Если вы вызываете метод который берет const ссылку, у вас нет гарантий, что ваш обьект не мутирует. Если вы принимаете const ссылку, у вас не гарантий что ваш обьект по ссылке не мутирует произвольно. Короче const контракт нигде и никем не принуждается, поэтому полагаться на него нельзя. Так что я рад что в C# не ввели эту дырявую и ненадежную систему.
                                                                                +5
                                                                                Просто нужно отрывать руки «программистам» которые делают const_cast нарушая контракт (стоит отметить, что не каждый const_cast контракт нарушает)

                                                                                И лично мне эта «дырявая и ненадежная система» много раз экономила время выдавая ошибки на этапе компиляции, а не где-то в рантайме с опозданием на Эн (Эм, если Эн мало) операций (вызовов, секунд, итераций — нужное подчеркнуть).
                                                                                  –3
                                                                                  Это замечательно, что эта система работает. Кроме случаев когда она не работает. Правда об этом вы узнаете в последнюю очередь, потому что при дебаге вы будете мысленно помечать код с const как надежный, и соответственно искать ошибку в другом месте.
                                                                                    +4
                                                                                    grep const_cast (это, кстати, ответ на вопрос, почему эти вещи называются так длинно)
                                                                          • UFO just landed and posted this here
                                                                              –4
                                                                              Какую такую багу? Чего вы добиваетесь вписыванием const везде где можно?
                                                                                +4
                                                                                Гарантии, что никто нигде не поменяет значение «случайно».
                                                                                  –7
                                                                                  «Никто» — это вы сами, а «нигде» — это в теле метода, который вы сами ниже пишите и который в ваших же интересах написать простым и обозримым? Вам не кажется, что что-то здесь не так? :) То же касается и мусорных m_. Программист, не могущий запомнить области видимости и контест переменных в коде с которым работает — профессионально некомпетентен.
                                                                                    +2
                                                                                    Даже если вы не допустите таких ошибок и вам это не нужно, вы сэкономите время мейнтейнерам. А если вы считаете что мейнтейнить должны только профессиональные и компетентные программисты то подумайте о том, что каждый компетентный программист когда-то был некомпетентным.
                                                                                      +1
                                                                                      В качестве мистера «никто» может выступить программист, который влез в этот код, когда вы уже год как уволились. Есть метод, у метода есть контракт — метод не изменяет переданный в него объект. Это значит, что при вызове этого метода мне не нужно блокировать объект на запись, если идёт работа в многопоточном окружении.

                                                                                      Другое дело в том, правильно ли это? Тут легко выстрелить себе в ногу, если кто-то изменит сигнатуру метода (хотя если кто-то это делает, не проверив все использования метода, то нужно ему бить по рукам), удалив этот контракт.

                                                                                      В C#/Java в этом случае действует презумпция виновности — если мы передаём в метод mutable объект, то предполагаем, что метод рано или поздно может изменить этот объект, поэтому обо всех блокировках лучше позаботиться заранее, или же в качестве аргумента этого метода принимать immutable обёртку над исходным объектом.
                                                                                        0
                                                                                        >В качестве мистера «никто» может выступить программист, который влез в этот код, когда вы уже год как уволились

                                                                                        Не вижу причин по которым работодатель вместо меня наймёт человека существенно глупее меня :).
                                                                                        Не могу понять откуда взялась страшилка о том, что будущие мейнтейнеры и текущие коллеги по команде — априорно круглые идиоты и поэтому код надо писать как для идиотов. Тут как-то был холивар на тему тернарного оператора — люди всерьёз утверждали, что шестистрочная конструкция (обхявление переменной, if-else со всеми скобками) православнее («проще» и «понятнее»), чем функционально аналогичная однострочная с использованием тернарного оператора.

                                                                                        >Есть метод, у метода есть контракт

                                                                                        Это совсем другое дело! Собственно, против контрактов в описанном вами применении я ничего не имею.

                                                                                        Я вообще, скорее, против мусорных префиксов агитировал :). И про «защиту» с помощью const от того, что «кто-то» что-то «случайно» испортит.
                                                                                          +3
                                                                                          Не могу понять откуда взялась страшилка о том, что будущие мейнтейнеры и текущие коллеги по команде — априорно круглые идиоты и поэтому код надо писать как для идиотов.

                                                                                          Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?
                                                                                          Brian Kernigan
                                                                                        +3
                                                                                        >«Никто» — это вы сами, а «нигде» — это в теле метода, который вы сами ниже пишите и который в ваших же интересах написать простым и обозримым? Вам не кажется, что что-то здесь не так? :) То же касается и мусорных m_. Программист, не могущий запомнить области видимости и контест переменных в коде с которым работает — профессионально некомпетентен.

                                                                                        Программист, заявляющий такое, никогда не работал в команде.
                                                                                          –2
                                                                                          Интересно. В вашей команде люди лезут менять код метода не пытаясь понять устройства и назначения содержащего его класса? Может ещё и глаза перед этим завязывают? В _таких_ командах, действительно, никогда не работал. И не вижу причин по которым это могло бы произойти в будущем. Аминь.
                                                                                            0
                                                                                            >В вашей команде люди лезут менять код метода не пытаясь понять устройства и назначения содержащего его класса?

                                                                                            Вас что-то не в ту степь понесло.
                                                                                            Вот как раз для того, чтобы понять устройство и назначение класса и его методов, и нужны эти мелкие хинты в виде m_ и прочего «мусора», как вы выражаетесь. И тело метода далеко не всегда «просто и обозримо», и писано оно далеко не всегда тем самым человеком, который на него в данный момент смотрит и пытается понять.
                                                                                              –3
                                                                                              >Вот как раз для того, чтобы понять устройство и назначение класса и его методов, и нужны эти мелкие хинты в виде m_ и прочего «мусора»

                                                                                              Попробуйте так и так. Без мусора всё существенно проще для понимания и красивее эстетически. Чем этот мусор вам помогает? Вы всё-равно должны понять назначение переменной. А поняв его, вы определите контекст. Ни одного повода делать это в противоположном направлении я не вижу. Зачем вам знать, что это переменная экземпляра, а не локальная если вы не знаете зачем она предназначена?

                                                                                              >И тело метода далеко не всегда «просто и обозримо»

                                                                                              Значит что-то надо поменять в консерватории. Нет?
                                                                                                +3
                                                                                                Брр, не знаю что вам там мерещится но дело просто в больших объёмах кода, и команде из нескольких человек когда зачастую не все из разработчиков знают как работает весь проект в целом, и вы удивитесь, но они и проект от этого никак не страдают. Потому что весь этот «информационный мусор» позволяет им сразу определить что перед ними лишь взглянув на имя переменной, или на определение метода.

                                                                                                вопрос на засыпку что и где изменит следующий метод?

                                                                                                void setValue(MyClass& newValue)
                                                                                                {
                                                                                                boards[current] = newValue;
                                                                                                }
                                                                                                  0
                                                                                                  В приведённом вами куске говнокода префикс ни как не поможет, увы. Сделает ещё более нечитаемым.
                                                                                                  m_boards[..] =
                                                                                                  Что изменилось? Сразу стало понятно что и где изменит этот метод???
                                                                                                    0
                                                                                                    Мне, по крайней мере, понятно, что если программист следовал соглашениям MS 90-х годов, то это присвоение за пределы класса не вылезет.
                                                                                                  0
                                                                                                  >Попробуйте так и так

                                                                                                  Смешно, да. Мои «пробы» закончились лет 10 назад.

                                                                                                  >Без мусора всё существенно проще для понимания и красивее эстетически.

                                                                                                  2 ситуации:
                                                                                                  1. с первого взгляда понятно, является ли переменная членом класса или же она локальна
                                                                                                  2. с первого взгляда НЕпонятно, является ли переменная членом или же она локальна

                                                                                                  Вы утверждаете, что второе — «проще для понимания»? Боюсь, нам придётся прекратить нашу дискуссию: с такой логикой я спорить не в силах.

                                                                                                  >Значит что-то надо поменять в консерватории. Нет?

                                                                                                  Да, а кто спорит? Лучше вообще «всё выкинуть и переписать заново на Эрланге».

                                                                                                  Вот только когда поработаете в реальном проекте, над которым только в текущий момент работают хотя бы 15 человек (и ещё столько же работали в прошлом), и когда нужно пофиксить баг «здесь и сейчас» (и именно пофиксить, а не «замазать»), а рефакторинг класса объёмом 2000 строк никак не укладывается в отведённый срок/бюджет (т.к. отрефакторить это полдела, нужно ещё прогнать весь набор тестов, которые не всегда автоматические и очень часто требуют ручного тестирования QA-специалистами, после чего обработать заведённые по результатам тестирования тикеты, пофиксить баги, снова прогнать тесты и так далее по кругу....) — вот тогда мы можем вернуться к данному разговору.
                                                                                                    0
                                                                                                    >2 ситуации:
                                                                                                    >Вы утверждаете, что второе — «проще для понимания»?

                                                                                                    Задайте себе вопрос — почему для вас второе НЕ проще для понимания. Метод перед глазами, объявления переменных видно с первого взгляда. Может переменная названа «говорящим» словом value? Ну и как вам в этом случае поможет префикс? Может метод у вас в 1000 строк? Ну и как префикс поможет понять что в этом методе делается и ЗАЧЕМ этой переменной что-то присваивается? Ну, будете вы и знать, что это не локальная переменная и ЧО?
                                                                                                    Причина того, что вы не понимаете нахера этой переменной что-то присваиватеся совсем не в том, что она не имеет префикса.
                                                                                                    Ну, и, если уж совсем жить без этого не можете — у вас в компании запрещено настраивать подсветку синтаксиса? Зачем вручную делать то, что компьютер сделает за вас гораздо лучше???

                                                                                                    >Вот только когда поработаете в реальном проекте

                                                                                                    Ай, перестаньте. Я предыдущие 8 лет работал над проектов в котором в отдельные моменты времени работало и по 30 человек и QA и ручные тесты и бюджет и тд. Это всё не повод писать говногод и покрывать его мусором. А первоначально проект достался вообще в таком виде, что мама-не-горюй — несколько поколений программистов училось на нём писать на новом для них языке, бизнес-логика была размазана по .jsp-шкам вперемешку с HTML разметкой, одних только обёрток для работы с БД было четыре или пять :). Если бы там были ещё и говнопрефиксы…
                                                                                      • UFO just landed and posted this here
                                                                                          +1
                                                                                          да, это охуенно.

                                                                                          чем труднее задачи, которые решаешь, тем больше хочется иметь инструментов со временем, а не изобретать свои.

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

                                                                                          а если такой цели нет — не нужно и брать набор инструментов для огранки статуи с точностью до микронов. возьмите обычный топор и им ебашьте в свое удовольствие.
                                                                                          с++ рулит.
                                                                                      0
                                                                                      А что это вы final FileScanTask fileTask пропустили? Отсутствие деления на декларацию/имплементацию, на мой взгляд, скорее, минус. В C++ я могу написать метод и непосредственно в классе (особенно, если он такой простой, как в вашем примере), а могу убрать его куда-нибудь вглубь, чтобы не засорять интерфейс. В джаве или шарпе приходится иногда мотать километры кода, чтобы найти декларацию какой-нибудь функции.
                                                                                      • UFO just landed and posted this here
                                                                                          +1
                                                                                          Code folding не поможет?
                                                                                            +1
                                                                                            Не всегда. Например, я иногда смотрю что-нибудь просто в консоли, удаленно. Поднимать какую-нибудь IDE только для того, чтобы свернуть код? Увольте.
                                                                                          +1
                                                                                          А вы код пишите в блокноте? То, что можно отдать для обработки компьютеру — НАДО отдать для обработку компьютеру. Зачем мне-то этим заниматься? Я нажимаю две кнопки и получаю этот списочек, если он мне вдруг понадобился. Мне не надо открывать отдельный файл и туда смотреть. Но, главное, мне не надо этот файл писать и поддерживать в актуальном состоянии!
                                                                                          Человек должен думать, а машина — работать. Выполнять на компьютере вручную работу компьютера — что может быть глупее…
                                                                                            +1
                                                                                            Я код пишу, главным образом, в MSVC, но при этом постоянно пользуюсь и линуксом. И как раз в MSVC очень удобно искать объявления методов и т.п. средствами IDE. Но случается и в блокноте писать (точнее, в gedit или вообще в nano) — там этих средств нет. С++ мне позволяет использовать оба подхода, с джавой или шарпом этого выбора не было бы.

                                                                                            Компьютер далеко не всегда может сделать всю работу за вас. Вон, в приведенном выше примере автор забыл поставить final — язык приучил его не заботиться о таких вещах. А плюсы дисциплинируют. В том, чтобы набрать 5-6 букв (const, &), уточняя свои требования, не вижу ничего плохого. Зато гибкость появляется во всем теле — хочешь по ссылке передавай параметры, хочешь — по значению (да еще и с собственным копированием). Да и пользователю труднее сделать ошибку и использовать ваш класс неправильно. Для относительно небольших проектов это, возможно, несущественно. В больших и тяжелых, которые пишут сотни людей, может быть очень критично.
                                                                                            0
                                                                                            Отсутствие деления на декларацию/имплементацию, на мой взгляд, скорее, минус.


                                                                                            Я теперь всегда буду вас вспоминать, когда какой-нибудь проект будет компилиться очередные полчаса, вместо нескольких секунд на каком-нибудь C#/Java/…
                                                                                            Да я знаю про Single Compilation Unit, но это уже костыли, да и не каждый чужой проект под него переведешь.
                                                                                              0
                                                                                              Да, такая проблема есть. Но у меня часто идет две-три компиляции параллельно, а я в это время отлаживаю еще один экземпляр. Зато работает оно потом не в пример быстрее любых джав — у нас это критично.
                                                                                                +3
                                                                                                блин, обожаю холивары.
                                                                                                — у вас есть декларации, это тупо — руками делать работу компьютера
                                                                                                — зато у вас хрен найдешь, что как работает нужно мотать километры кода
                                                                                                — ок, зато у вас все тормозит при компиляции
                                                                                                — ну уж позвольте, зато потом летает «не в пример быстрее любых джав» (и прочих пхп, допишу я)
                                                                                                — ок, зато у вас куча лишних символов в описании, хрен поймешь, а у нас код понятный и простой
                                                                                                — да? зато у нас можно сразу объявить, что объект не изменяется, и это фича, а у вас нужен костыль
                                                                                                — зато у нас есть GC
                                                                                                — который не работает, и вообще, ручное управление памятью — это кошерно
                                                                                                — ага, знаем мы это ручное управление памятью
                                                                                                … честно слово, от души поднимает настроение. спасибо всем экспертам, очень приятно читать комментарии!
                                                                                                  0
                                                                                                  блин, обожаю холивары.
                                                                                                  — у вас есть декларации, это тупо — руками делать работу компьютера
                                                                                                  — зато у вас хрен найдешь, что как работает нужно мотать километры кода
                                                                                                  — ок, зато у вас все тормозит при компиляции
                                                                                                  — ну уж позвольте, зато потом летает «не в пример быстрее любых джав» (и прочих пхп, допишу я)
                                                                                                  — ок, зато у вас куча лишних символов в описании, хрен поймешь, а у нас код понятный и простой
                                                                                                  — да? зато у нас можно сразу объявить, что объект не изменяется, и это фича, а у вас нужен костыль
                                                                                                  — зато у нас есть GC
                                                                                                  — который не работает, и вообще, ручное управление памятью — это кошерно
                                                                                                  — ага, знаем мы это ручное управление памятью
                                                                                                  … честно слово, от души поднимает настроение. спасибо всем экспертам, очень приятно читать комментарии!
                                                                                              +2
                                                                                              >И писать его проще, не надо про думать про &, const, :: и т.д.

                                                                                              А зачем про это «думать»? После нескольких лет это идёт на полном автомате.
                                                                                                –2
                                                                                                Так если идет на полном автомате, может они вообще не нужны? Так, мысль вслух. :)
                                                                                                  +1
                                                                                                  Иногда нужны, иногда не нужны, в зависимости от задачи.
                                                                                                  И на полном автомате идёт именно нужная форма.
                                                                                                0
                                                                                                class DetectionManager {

                                                                                                public: Status GetDetectionStatus(FileScanTask fileTask) const {
                                                                                                return m_detector.GetDetectionStatus(fileTask);
                                                                                                }



                                                                                                разницы даже нет
                                                                                                  0
                                                                                                  Именно. А зачем тогда её делают и пишут как автор привел?
                                                                                                    –1
                                                                                                    Людям жаль потраченных лет. Ошибки молодости стоят дорого)
                                                                                              +5
                                                                                              Там нет перешаблонированности. Хотя C# критикуется за «синтаксический сахар», в нём есть то, что необходимо большинству разработчиков, в C++ же есть многое, что необходимо для реализации библиотек на нём (хотя большинству всё равно, как они реализованы), а писать, скажем так, прикладной код, на нём неудобно.
                                                                                                +3
                                                                                                > Я мало знаком с C#, но можно пример? :) Ну, в смысле, вещей, над которыми надо корпеть в плюсах и совсем не надо в шарпе?

                                                                                                «Вывести на экран все строки текстового файла, в которых более трех слов, отсортированные по алфавиту.»

                                                                                                > вещей, над которыми надо корпеть в плюсах...

                                                                                                The Dark Side of C++
                                                                                                C++ FQA Lite
                                                                                                • UFO just landed and posted this here
                                                                                                    0
                                                                                                    > Давайте, для интереса, напишем решение этой задачи: вы на c#, я на c++ и сравним результаты. :)

                                                                                                    Давайте.

                                                                                                    > Я уже указывал в комментариях, что не нужно отказываться от мощи чудесный фреймворков и библиотек.

                                                                                                    Ок, только без фанатизма; скажем, можно Boost. Но желательно также приложить вариант, ограничивающийся только стандартной библиотекой.

                                                                                                    > Подобного говна можно найти про любой язык. :)

                                                                                                    Но только про C++ его так много.
                                                                                                    • UFO just landed and posted this here
                                                                                                        +11
                                                                                                        File.ReadAllLines("test.txt")
                                                                                                            .Where(line => line.Split(' ').Length > 3)
                                                                                                            .OrderBy(s => s)
                                                                                                            .Run(Console.WriteLine);
                                                                                                        • UFO just landed and posted this here
                                                                                                            +1
                                                                                                            Да, на Питоне будет что-то типа такого:
                                                                                                            lines = open('test.txt').readlines()
                                                                                                            for line in sorted( filter(lambda x: len(x.split(' ')) > 3, lines) ) :
                                                                                                            	print line.rstrip('\n')


                                                                                                            При желании всё это вытягивается в одну строку, я разбил на несколько чтобы влезло по ширине.

                                                                                                            Кстати, есть другие варианты? Я с Питоном знаком не то чтобы очень плотно…
                                                                                                              +1
                                                                                                              А, ну да, чего это я:
                                                                                                              from sys import stdout
                                                                                                              
                                                                                                              lines = open('test.txt').readlines()
                                                                                                              stdout.writelines( sorted( filter(lambda x: len(x.split(' ')) > 3, lines) ) )
                                                                                                              

                                                                                                              Разбито на 2 строки, опять же, чтобы влезло по ширине.
                                                                                                                +5
                                                                                                                with open('test.txt') as lines: 
                                                                                                                    stdout.writelines(sorted(_ for _ in lines if len(_.split())>3))

                                                                                                                но правильней даже так:

                                                                                                                with open('test.txt') as lines: 
                                                                                                                    stdout.writelines(sorted(_ for _ in lines if _.count(' ')>2)
                                                                                                                  +1
                                                                                                                  А зачем делать
                                                                                                                  with open('test.txt') as lines

                                                                                                                  если можно короче
                                                                                                                  lines = open('test.txt')

                                                                                                                  с тем же самым результатом?
                                                                                                                    +1
                                                                                                                    1) С таким способом можно записать в одну строку
                                                                                                                    2) Это правильно, т.к. with сам открывает и закрывает файл, переменная lines будет существовать только в своей области видимости там, где используется, а не висеть до конца выполнения программы.
                                                                                                                      +2
                                                                                                                      Так можно же вообще без этой переменной обойтись:

                                                                                                                      stdout.writelines(sorted(_ for _ in open('test.txt') if _.count(' ')>2))

                                                                                                                      :)
                                                                                                                        0
                                                                                                                        Вот и довели до идеала =)
                                                                                                                        получилось даже красивей, чем в шарпе ))
                                                                                                                          0
                                                                                                                          Самое интересное, что решение неверное :)

                                                                                                                          Вместо «open('test.txt')» должно быть «open('test.txt').readlines()», что даёт ещё +12 символов.
                                                                                                                          0
                                                                                                                          А _.count(' ') считает просто количество пробелов?
                                                                                                                            0
                                                                                                                            Да, только считает… смысл искать пробелы и делить для этого список, если можно только найти пробелы?
                                                                                                                              0
                                                                                                                              Например, если идет несколько пробелов подряд.
                                                                                                                                0
                                                                                                                                С одной стороны, да, косяк ))) с другой split(" ") тогда тоже даст неверные результаты, а вот split без параметров — да, тогда действительно лучший вариант )
                                                                                                              +1
                                                                                                              С использованием Qt решение будет выглядеть где-то примерно так:

                                                                                                              QFile file("test.txt");
                                                                                                              file.open( QIODevice::ReadOnly );
                                                                                                              QStringList lines = QString::fromLocal8Bit file.readAll())
                                                                                                              		.split("\n").filter(QRegExp("(\\S+\\s+){3,}\\S+"));
                                                                                                              lines.sort();
                                                                                                              foreach (QString line, lines)
                                                                                                              	qDebug() << line;
                                                                                                              


                                                                                                              И да, использованная здесь QtCore вполне укладывается в «без фанатизма» и «по минимуму» — она весит чуть более 2.5 мегабайт.
                                                                                                              А сколько будет весить рантайм для вашего решения? ;)

                                                                                                              Кстати, покажите как изменится ваш код, если текст в файле кодирован, скажем, в UTF16, а вам нужно вывести его в текущей локали.
                                                                                                                0
                                                                                                                Encoding localEncoding = new Encoding(requiredCodePage);

                                                                                                                File.ReadAllLines("test.txt")
                                                                                                                .Where(line => line.Split(' ').Length > 3)
                                                                                                                .OrderBy(s => s)
                                                                                                                .Select(s => localEncoding.GetString(Encoding.Unicode.GetBytes(s)))
                                                                                                                .Run(Console.WriteLine);


                                                                                                                Понятно, что requiredCodePage должен быть тем, что вам нужен.

                                                                                                                Но именно перевода из Unicode в текущую локаль делать не надо — это происходит автоматически: Unicode (UTF16) — родное представление строк в .NET. Т.е. код выше — просто демонстрация.
                                                                                                                  0
                                                                                                                  Понятно, спасибо.

                                                                                                                  Для моего варианта изменится одна строчка:
                                                                                                                  QFile file("test.txt");
                                                                                                                  file.open(QIODevice::ReadOnly);
                                                                                                                  QStringList lines =
                                                                                                                  	QTextCodec::codecForName(requiredCodePage)->toUnicode(file.readAll())
                                                                                                                  	.split("\n").filter(QRegExp("(\\S+\\s+){3,}\\S+"));
                                                                                                                  lines.sort();
                                                                                                                  foreach (QString line, lines)
                                                                                                                  	qDebug() << line;


                                                                                                                  Самое интересное: объёмы нашх решений отличаются считанными байтами :)
                                                                                                                    0
                                                                                                                    В принципе, они и не должны особенно отличаться. :-) Конечно, я бы мог сократить решение на строчку — но кому это надо?

                                                                                                                    Как человек, прошедший через C, C++, Java и C# — могу сказать, что этот ряд отражает спектр решений от «ближе к железу» до «ближе к задаче».
                                                                                                                      0
                                                                                                                      >В принципе, они и не должны особенно отличаться. :-)

                                                                                                                      Как это «не должны»? Тред-то пошёл от утверждения «в плюсах приходится корпеть над тем, что в шарпе делается легко и непринуждённо» ;)
                                                                                                                        0
                                                                                                                        Библиотеки решают. :-)
                                                                                                                          0
                                                                                                                          Дык о чём и речь :)
                                                                                                                            +1
                                                                                                                            >> Библиотеки решают. :-)
                                                                                                                            > Дык о чём и речь :)

                                                                                                                            Можно задачу без библиотек. Например: вернуть из первой функции другую функцию, замыкающую по ссылке локальную переменную первой функции.
                                                                                                                              0
                                                                                                                              Это не задача, а решение
                                                                                                                                0
                                                                                                                                Хорошо, пусть решение. Так вы можете предоставить код решения на C++? Так и быть, можно Boost, Qt и Loki.

                                                                                                                                Требуется что-то вроде такого решения на псевдокоде:
                                                                                                                                Foo : () → (int → int) = 
                                                                                                                                () ↦ {
                                                                                                                                  valueToBeClosed : int = 3;
                                                                                                                                  assignNewValue : int → int =
                                                                                                                                    value ↦ {
                                                                                                                                      result : int = valueToBeClosed;
                                                                                                                                      valueToBeClosed = value;
                                                                                                                                      return result;
                                                                                                                                    }
                                                                                                                                  return assignNewValue;
                                                                                                                                }

                                                                                                                                Использование:
                                                                                                                                foo : int → int = Foo();
                                                                                                                                WiteLine( foo(21) ); // 3
                                                                                                                                WiteLine( foo(42) ); // 21
                                                                                                                                  0
                                                                                                                                  Такие замыкания в паре с мутабельной лямбдой используют в Scheme для имитации объектов. Зачем это в С++, если можно вернуть объект?
                                                                                                                                  ideone.com/qnbrm
                                                                                                                                    –1
                                                                                                                                    > Такие замыкания в паре с мутабельной лямбдой используют в Scheme для имитации объектов.

                                                                                                                                    А схемщики считают, что это объекты в ООП служат для имитации замыканий.

                                                                                                                                    > ideone.com/qnbrm

                                                                                                                                    Вот это и называется «вещами, над которыми надо корпеть в плюсах и совсем не надо в шарпе». Ты не можешь просто замкнуть переменную по ссылке. В момент, когда такая задача возникла, тебе надо изменить окружающий код, заморачиваться с передачей по значению ([=]) ссылки (указателя shared_ptr). А без этого программа скомпилируется без всяких предупреждений, и, самое страшное, не исключено что при определённых условиях UB будет проявляться так, что создаст видимость правильной работы.
                                                                                                                                      +2
                                                                                                                                      Схемщиков тута нету.
                                                                                                                                      Вот это и называется «вещами, над которыми надо корпеть в плюсах и совсем не надо в шарпе».

                                                                                                                                      Нет, не называется. Что ожидалось, понятно: «Так и быть, можно Boost, Qt и Loki.», а было представлено простое решение, минимально отличающееся от псевдокода, но сохранить лицо надо было. Вот я со своим минимальным опытом знаю, что shared_ptr по ссылке передавать нельзя, почему это должен кто-то еще не знать, кроме программиста на C#, который С++ не видел, не понятно.
                                                                                                                                      В момент, когда такая задача возникла

                                                                                                                                      Это не задача. Это решение какой-то задачи, не самое лучше. В C# зло так делать, если нужно вернуть объект с состоянием — возвращай объект с состоянием, а не делай грязные лямбды на пустом месте. Хотя отсутствие operator() мешает такому использованию, да, но вряд ли оно и будет таким.
                                                                                                                                        0
                                                                                                                                        > Что ожидалось, понятно: «Так и быть, можно Boost, Qt и Loki.», а было представлено простое решение, минимально отличающееся от псевдокода, но сохранить лицо надо было.

                                                                                                                                        Какое «сохранить лицо», «ожидалось» и «программист на C#, который С++ не видел»? Я прекрасно знаю, как подобный код пишется на C++. Упомянув библиотеки, я всего лишь имел в виду, что, раз уж в C++ нет первоклассных функций, допускается использовать библиотечные функторы из boost, Loki, std::tr1 или вот из нового std.

                                                                                                                                        > В момент, когда такая задача возникла

                                                                                                                                        Вы не улавливаете контекста. Я имел в виду, что если у вас уже есть функция с int valueToBeClosed = 3;, то вы не можете просто добавить замыкание, не меняя его контекст. Вы должны не забыть превратить окружение (valueToBeClosed) в ссылку (в общем смысле, не C++) на нестековое значение и передать её по значению.

                                                                                                                                        > Это решение какой-то задачи, не самое лучше.

                                                                                                                                        Вполне идиоматичное решение. Подобным состоянием может быть датчик случайных чисел, или какой другой Enumerator. От пользователя внутренний итератор скрыт, он получает просто генератор (возможно, бесконечной) последовательности в виде функции.

                                                                                                                                        > В C# зло так делать, если нужно вернуть объект с состоянием — возвращай объект с состоянием, а не делай грязные лямбды на пустом месте.

                                                                                                                                        Ерунда. Зачем мне передавать объект с состоянием, если я хочу это состояние скрыть от пользователя? Получится объект с одной функцией и недоступным пользователю состоянием. Так почему бы сразу не вернуть одну лишь функцию, зачем плодить сущности?
                                                                                                                                          +1
                                                                                                                                          Я прекрасно знаю, как подобный код пишется на C++.

                                                                                                                                          Тогда зачем это спрашивать у меня, нужно самому писать и говорить так и так, а не троллить, упоминая Qt. Конечно не знали до текущего момента.
                                                                                                                                          Вы не улавливаете контекста. Я имел в виду, что если у вас уже есть функция с int valueToBeClosed = 3;, то вы не можете просто добавить замыкание, не меняя его контекст.

                                                                                                                                          У меня есть функция и я внезапно решил возвратить из нее мутабельную лямбду? Лично я решаю это вместе с написанием ее типа. Перенос из стека в кучу можно сделать непосредственно перед return, так что сам код конструктора можно не отравлять лишними разыменованиями.
                                                                                                                                          Подобным состоянием может быть датчик случайных чисел, или какой другой Enumerator

                                                                                                                                          Потому я и говорил о задаче и решении. Выдать такую-то ФВП — не задача, а решение. Интерфейс генератора — ок.
                                                                                                                                          На С++ решение функтор с кодом, размером меньше, чем у такой лямбды на C#, но намного более прозрачный по сути, чем вот это схемоподобное нечто (в том числе и в плане документации — wiki.thrust.googlecode.com/hg/html/classthrust_1_1random_1_1linear__feedback__shift__engine.html)
                                                                                                                                          Задачу нужно вспоминать до решения, если цель не потроллить конечно. В C# нет operator() и ваше решение обходит это, хотя станет не весело, когда у этого генератора появляются параметры, отличные от простого seed, как у того, что по ссылке и все равно придется делать объект, ну или совсем превращать C# в схему.
                                                                                                                                          Ерунда. Зачем мне передавать объект с состоянием, если я хочу это состояние скрыть от пользователя?

                                                                                                                                          Что изменяет состояние класса понятно по его объявлению. Это важно, const-методы можно не лочить в многопоточном приложении, например.
                                                                                                                                          Изменяемость состояния псевдообъекта на замыкании не понятна, будь добр смотри в исходники.
                                                                                                                                            –1
                                                                                                                                            > Тогда зачем это спрашивать у меня, нужно самому писать и говорить так и так, а не троллить

                                                                                                                                            Я никого не тянул за язык, просто deMonteCristo спросил «пример… вещей, над которыми надо корпеть в плюсах и совсем не надо в шарпе». Я просто предоставил два примера, с меня и взятки гладки. Какой троллинг, прости господи?

                                                                                                                                            > В C# нет operator() и ваше решение обходит это

                                                                                                                                            Это как раз наоборот, в C++ нет первоклассных функций и не решена upwards funarg problem, так что обходят кривым способом с помощью operator ().

                                                                                                                                            > Конечно не знали до текущего момента.

                                                                                                                                            Это грязные инсинуации, благородному дону не пристало. Не только знал, но ещё до публикации задачи написал proof-of-concept реализацию на C# и вариант на C++0x, воспроизводящий UB.

                                                                                                                                            Исходный псевдокод:
                                                                                                                                            Foo : () → (int → int) = 
                                                                                                                                            () ↦ {
                                                                                                                                              valueToBeClosed : int = 3;
                                                                                                                                              assignNewValue : int → int =
                                                                                                                                                value ↦ {
                                                                                                                                                  result : int = valueToBeClosed;
                                                                                                                                                  valueToBeClosed = value;
                                                                                                                                                  return result;
                                                                                                                                                }
                                                                                                                                              return assignNewValue;
                                                                                                                                            }


                                                                                                                                            Подстрочный перевод на C#:
                                                                                                                                            static Func<int, int> Foo()
                                                                                                                                            {
                                                                                                                                                int valueToBeClosed = 3;
                                                                                                                                            
                                                                                                                                                Func<int, int> assignNewValue = value =>
                                                                                                                                                {
                                                                                                                                                    var result = valueToBeClosed;
                                                                                                                                                    valueToBeClosed = value;
                                                                                                                                                    return result;
                                                                                                                                                };
                                                                                                                                            
                                                                                                                                                return assignNewValue;
                                                                                                                                            }


                                                                                                                                            Аналогичный вариант на C++, содержащий скрытую ошибку:
                                                                                                                                            std::function<int (int)> Foo()
                                                                                                                                            {
                                                                                                                                                int valueToBeClosed = 3;
                                                                                                                                            
                                                                                                                                                auto const assignNewValue = [&] (int value) -> int
                                                                                                                                                {
                                                                                                                                                    auto const result = valueToBeClosed;
                                                                                                                                                    valueToBeClosed = value;
                                                                                                                                                    return result;
                                                                                                                                                };
                                                                                                                                            
                                                                                                                                                return assignNewValue;
                                                                                                                                            }
                                                                                                                                              +1
                                                                                                                                              std::function<int (int)> Foo()
                                                                                                                                              {
                                                                                                                                                  int valueToBeClosed = 3;
                                                                                                                                              
                                                                                                                                                  auto const assignNewValue = [=](int value) mutable -> int
                                                                                                                                                  {
                                                                                                                                                      auto const result = valueToBeClosed;
                                                                                                                                                      valueToBeClosed = value;
                                                                                                                                                      return result;
                                                                                                                                                  };
                                                                                                                                              
                                                                                                                                                  return assignNewValue;
                                                                                                                                              }
                                                                                                                                              


                                                                                                                                              Вот так, если я правильно понимаю механизм лямбд в C++, будет без UB.

                                                                                                                                              Захватываем по значению, объявляем лямбду mutable и спокойно меняем захваченное значение ибо оно внутри объекта, реализующего лямбду.
                                                                                                                                                –1
                                                                                                                                                > и спокойно меняем захваченное значение ибо оно внутри объекта, реализующего лямбду.

                                                                                                                                                А если мы вызываем assignNewValue(31) перед выходом из Foo() и предполагаем, что вызов таки изменит нашу локальную переменную valueToBeClosed?
                                                                                                                                                  0
                                                                                                                                                  Это как это мы так предполагаем, если мы только что сами ясно написали, что данная лямбда осуществляет захват по значению и оригинал менять не может?
                                                                                                                                                    0
                                                                                                                                                    > Это как это мы так предполагаем, если мы только что сами ясно написали, что данная лямбда осуществляет захват по значению и оригинал менять не может?

                                                                                                                                                    Ну, а надо по ссылке!
                                                                                                                                                0
                                                                                                                                                >Я просто предоставил два примера, с меня и взятки гладки.

                                                                                                                                                В итоге первый пример легко и непринуждённо решается с помощью Qt ничуть не сложнее, чем на шарпе, высосанный из пальца второй тоже недалеко от этого ушёл. Ч.т.д.

                                                                                                                                                Собственно, если вы переформулируете своё заявление как «есть вещи, над которыми мне приходится корпеть в плюсах», то все вопросы моментально отпадут.
                                                                                                                                                  0
                                                                                                                                                  > В итоге первый пример легко и непринуждённо решается с помощью Qt ничуть не сложнее, чем на шарпе

                                                                                                                                                  Легко и непринуждённо, ничуть не сложнее? :) Хоть в одном из предложенных C++-вариантов навскидку (человеком, впервые читающим код) вычисление декомпозируется на стандартные ФВП: фильтрация—сортировка—проекция—итерация… (аггрегация, свёртка, zip, unfold, etc)? Подобные Linq-запросы на C# пишутся секунд за 30 без циклов, условных операторов и прочей императивщины с изменением состояний. C++ по скорости написания кода и скорости его восприятия даже близко не стоит.

                                                                                                                                                  > второй тоже недалеко от этого ушёл.

                                                                                                                                                  Путём решения фунарг-проблемы на ручной тяге?

                                                                                                                                                  > Собственно, если вы переформулируете своё заявление как «есть вещи, над которыми мне приходится корпеть в плюсах», то все вопросы моментально отпадут.

                                                                                                                                                  Это не ко мне, изначально не я формулировал это заявление. Я просто привёл пару простых примеров.
                                                                                                                                                    0
                                                                                                                                                    >Легко и непринуждённо, ничуть не сложнее? :) Хоть в одном из предложенных C++-вариантов навскидку (человеком, впервые читающим код) вычисление декомпозируется на стандартные ФВП: фильтрация—сортировка—проекция—итерация… (аггрегация, свёртка, zip, unfold, etc)?

                                                                                                                                                    Что вам не понятно в этом решении? (кстати, извиняюсь за опечатку: там не хватает открывающей скобки "(" после «fromLocal8Bit»)

                                                                                                                                                    Прочитать файл, декодировав из текущей кодировки, разбить по строкам, отфильтровать по паттерну, затем отсортировать и вывести построчно. Скажите пожалуйста, на каком месте лично вы споткнулись.
                                                                                                                                                      0
                                                                                                                                                      Да потроллить чел зашел, что неясного.
                                                                                                                                                        –1
                                                                                                                                                        > Что вам не понятно в этом решении? (кстати, извиняюсь за опечатку: там не хватает открывающей скобки "(" после «fromLocal8Bit»)

                                                                                                                                                        Мне всё понятно, даже синтаксические ошибки могу в уме исправлять :) Но время на восприятие плюсового намного выше, чем у аналогичного C#-кода. И дело не только в приведённых кратких фрагментах, я говорю на основании опыта промышленного использования C++ (тогда ещё без 0x, но уже с блэкджеком) и C#. В последнем благодаря Linq обработка коллекций любых типов выглядит одинаково и идиоматично, легко узнаваема.

                                                                                                                                                        А ваш код вполне нормален, где-то недалеко от максимума выразительности, которую можно выжать из языка. Правда, я хотел бы увидеть хоть какие-то ФВП общего назначения, получающие лямбды (предикаты фильтрации, сравнения, селектор, etc), но сходу предложенный пример, как оказалось, решился частными библиотечными функциями для работы со строками. Ну и бог с ним.
                                                                                                                                              0
                                                                                                                                              >>> Такие замыкания в паре с мутабельной лямбдой используют в Scheme для имитации объектов.

                                                                                                                                              >> А схемщики считают, что это объекты в ООП служат для имитации замыканий.

                                                                                                                                              > Схемщиков тута нету.

                                                                                                                                              Какая разница, есть ли тута схемщики. Я имел в виду слова (емнип) Нормана Адамса «Objects are a poor man's closures», которые считал достаточно известными.
                                                                                                                        0
                                                                                                                        > И да, использованная здесь QtCore вполне укладывается в «без фанатизма» и «по минимуму» — она весит чуть более 2.5 мегабайт.
                                                                                                                        А сколько будет весить рантайм для вашего решения? ;)


                                                                                                                        Какой-то странный подход, сравнивать среду выполнения и библиотеку.
                                                                                                                        1) Дополнительных библиотек в моём коде не требуется, так что при наличии единожды установленного .NET 4.0 оверхед 0 мегабайт.
                                                                                                                        2) Если учитывать вес рантайма, то полный дистрибутив dotNetFx40_Full_x86_x64.exe весит 48.1 Мб, достаточный дистрибутив dotNetFx40_Client_x86_x64.exe — 41.0 Мб. Если верить офсайту Qt, то даже без SDK (который за гигабайт), просто предкомпилированные пользовательские библиотеки весят от 200 Мб.
                                                                                                                          0
                                                                                                                          > просто предкомпилированные пользовательские библиотеки весят от 200 Мб
                                                                                                                          Если мне не изменяет память, там не просто dll'ки. Там еще вся документация (в моем archlinux это пакет на 141 мегабайт), все утилитки типа дизайнера, сборки библиотек для отладки, демонстрационные примеры. Нет только IDE.
                                                                                                                            0
                                                                                                                            Библиотеки Qt весят 31 мегабайт. Хотите — поставьте себе в системе Qt и не парьтесь.

                                                                                                                            Вот только если вы захотите распространять свою программу на Qt, можете вместе с ней кинуть пару нужных dll и всё. А на сишлаке хочешь — не хочешь, а весь .NET Framework, будь добр, поставь!
                                                                                                                              0
                                                                                                                              > Вот только если вы захотите распространять свою программу на Qt, можете вместе с ней кинуть пару нужных dll и всё.

                                                                                                                              Тут тройку dll, там пару тех же dll…

                                                                                                                              > А на сишлаке хочешь — не хочешь, а весь .NET Framework, будь добр, поставь!

                                                                                                                              В современных операционках от Microsoft фреймворк уже предустановлен, т.е. идёт как часть системы. В операционках 10-летней давности фреймворка может и не быть, но, как правило, у клиентов он всё равно уже установлен с другим софтом типа GTA IV или AutoCAD.
                                                                                                                              0
                                                                                                                              1. При наличии единожды установленного Qt оверхед 0 мегабайт. Я вам даже больше скажу: при наличии единожды установленного $anything оверхед будет 0 мегабайт :)

                                                                                                                              2. Просто предкомпилированные пользовательские библиотеки весят 55 мегабайт в распакованном виде (и 18 мегабайт в виде тупого ZIP-а, сколько будет весить инсталлятор прикиньте сами, я не в курсе, какой там алгоритм сжатия используется) и включают в себя

                                                                                                                              Qt3Support4.dll
                                                                                                                              QtAssistantClient4.dll
                                                                                                                              QtCLucene4.dll
                                                                                                                              QtCore4.dll
                                                                                                                              QtDesigner4.dll
                                                                                                                              QtDesignerComponents4.dll
                                                                                                                              QtGui4.dll
                                                                                                                              QtHelp4.dll
                                                                                                                              QtNetwork4.dll
                                                                                                                              QtOpenGL4.dll
                                                                                                                              QtScript4.dll
                                                                                                                              QtScriptTools4.dll
                                                                                                                              QtSql4.dll
                                                                                                                              QtSvg4.dll
                                                                                                                              QtTest4.dll
                                                                                                                              QtWebKit4.dll
                                                                                                                              QtXml4.dll
                                                                                                                              QtXmlPatterns4.dll
                                                                                                                                –1
                                                                                                                                > При наличии единожды установленного Qt оверхед 0 мегабайт. Я вам даже больше скажу: при наличии единожды установленного $anything оверхед будет 0 мегабайт :)

                                                                                                                                Так а в чём тогда цимес уделять столько внимания размерам дистрибутивов рантаймов?

                                                                                                                                > Просто предкомпилированные пользовательские библиотеки весят 55 мегабайт в распакованном виде (и 18 мегабайт в виде тупого ZIP-а, сколько будет весить инсталлятор прикиньте сами, я не в курсе, какой там алгоритм сжатия используется)

                                                                                                                                Ещё можно приплюсовать размер плюсового рантайма (vcredist*.exe, Visual C++ 2010 Runtime Redistributable Package), его ж у пользователя тоже может не быть. И в итоге что получится? А хрен его знает, мне абсолютно лень считать, но да — мегабайтов 30 выиграет у .NET'а, HUGE SUCCESS!
                                                                                                                                  +1
                                                                                                                                  >Ещё можно приплюсовать размер плюсового рантайма (vcredist*.exe, Visual C++ 2010 Runtime Redistributable Package), его ж у пользователя тоже может не быть

                                                                                                                                  А можно и не плюсовать, взяв mingw-сборку. Размер mingwm10.dll подсказать? У неё в депенденсах только либы, входящие в стандартную поставку даже в Windows XP, не говоря уже о более поздних версиях.

                                                                                                                                  >И в итоге что получится? А хрен его знает, мне абсолютно лень считать, но да — мегабайтов 30 выиграет у .NET'а, HUGE SUCCESS!

                                                                                                                                  В итоге получится, что требование «только стандартная библиотека, ну максимум буст» является неудачной попыткой получить фору, т.к. даже использование Qt в полном комплекте сопоставимо с использованием .Net фреймворка.

                                                                                                                                  Ну, это если вы следили за контекстом, конечно…
                                                                                                                                    –1
                                                                                                                                    > В итоге получится, что требование «только стандартная библиотека, ну максимум буст» является неудачной попыткой получить фору

                                                                                                                                    Да нет, просто опасался получить решение в одну строку вида superlib::do_some_magic(), где функция берётся из какой-то хитрой никому не известной специализированной библиотеки. А Qt ок, почему нет.
                                                                                                                            0
                                                                                                                            Тут что-то функциональщиной больше попахивает. На Haskell тоже можно в одну строку всё решение записать, но дело не в этом. Вряд ли сейчас на С++ невозможно реализовать нечто подобное. Просто в .NET Framework уже много готового.
                                                                                                                            0
                                                                                                                            std::wstring?
                                                                                                                            • UFO just landed and posted this here
                                                                                                                                0
                                                                                                                                Для юникода есть ICU
                                                                                                                                • UFO just landed and posted this here
                                                                                                                                    0
                                                                                                                                    Да, действительно. Извиняюсь.
                                                                                                                                  0
                                                                                                                                  Есть еще std::locale и иже с ним.
                                                                                                                                    0
                                                                                                                                    В С++0x добавили unicode-строки вроде ж, да?
                                                                                                                                  0
                                                                                                                                  Ну, то же, что у тебя, можно и чуть покороче записать в принципе. Что-то из серии:
                                                                                                                                  #include <algorithm>
                                                                                                                                  #include <fstream>
                                                                                                                                  #include <iostream>
                                                                                                                                  #include <iterator>
                                                                                                                                  #include <set>
                                                                                                                                  #include <string>
                                                                                                                                   
                                                                                                                                  using namespace std;
                                                                                                                                   
                                                                                                                                  int main()
                                                                                                                                  {
                                                                                                                                          multiset<string> lines;
                                                                                                                                          ifstream fin("in.txt");
                                                                                                                                          string nextLine;
                                                                                                                                          while (getline(fin, nextLine))
                                                                                                                                                  if (count(nextLine.begin(), nextLine.end(), ' ') + 1 > 3)
                                                                                                                                                          lines.insert(nextLine);
                                                                                                                                          
                                                                                                                                          copy(lines.begin(), lines.end(), ostream_iterator<string>(cout, "\n"));
                                                                                                                                  		
                                                                                                                                          return 0;
                                                                                                                                  }
                                                                                                                                  


                                                                                                                                  Кстати, работать возможно будет побыстрее, чем пример на сишлаке.
                                                                                                                                  +5
                                                                                                                                  >Ок, только без фанатизма; скажем, можно Boost. Но желательно также приложить вариант, ограничивающийся только стандартной библиотекой.

                                                                                                                                  Ага, т.е. вы будете использовать целый .Net Framework, а вашему сопернику — по-минимуму?

                                                                                                                                  А давайте посоревнуемся, кто лучше плавает, вы или я: я буду на катере, а вы вручную (ну максимум можно ласты). Согласны? :)
                                                                                                                                • UFO just landed and posted this here
                                                                                                                                    +2
                                                                                                                                    Если в первую очередь читать такого качества «критику» языка, можно так никогда и не начать программировать. Такого рода поливаний дерьмом можно найти более 9000 для любого языка. В большинстве своём они имеют мало общего с действительностью, но вы, читая их сразу после Hello World, не сможете отличить описание реальных проблем от троллинга или поста очередного ниасилятора.
                                                                                                                                    • UFO just landed and posted this here
                                                                                                                                        0
                                                                                                                                        Волка бояться — в лес не ходить.
                                                                                                                                      • UFO just landed and posted this here
                                                                                                                                      0
                                                                                                                                      Для интереса имеет смысл писать без использования библиотек.
                                                                                                                                      И на жаве, до кучи.
                                                                                                                                      • UFO just landed and posted this here
                                                                                                                                          0
                                                                                                                                          Ну так я имел ввиду и без стандартной в том числе.
                                                                                                                                            0
                                                                                                                                            В чём заключается глубокий смысл неиспользования стандартной библиотеки, если она является неотъемлемой частью языка?
                                                                                                                                              0
                                                                                                                                              Чтобы не изобретать задачу, которой нет в стандартных библиотеках сравниваемых языков?
                                                                                                                                                +1
                                                                                                                                                Стандартная библиотека есть всегда. Какой смысл сравнивать языки решая задачу без использования стандартной библиотеки? Это всё равно, что сказать «посчитайте факториал, только не используя умножение». Что вам даст такое сравнение?
                                                                                                                                                  +1
                                                                                                                                                  Речь, насколько я понимаю, идёт о том, чтобы сравнить лаконичность и читабельность языков. Если в одном есть функция факториала, а в другом нет, естественно программа его вычисляющая будет лаконичней и читабельней на первом.
                                                                                                                                                0
                                                                                                                                                реализация алгоритма средствами самого языка.
                                                                                                                                                  0
                                                                                                                                                  Как я уже писал — стандартная библиотека это неотъемлемая часть языка. Так что средствами стандартной библиотеки — это и есть средствами самого языка.
                                                                                                                                                    0
                                                                                                                                                    Не писали вы для контроллеров.
                                                                                                                                                      0
                                                                                                                                                      Для микроконтроллеров не писал, писал для железяк на ARM. Только там был не С++, а Embedded C++, к которому, впрочем, стандартная библиотека прилагалась, хоть ею никто и не пользовался в силу привычек, традиций и ещё каких-то непонятных заморочек.

                                                                                                                                                      Но всё-таки Embedded C++ это не совсем С++, там как правило нет поддержки исключений и часто нет поддержки шаблонов (хотя у нас была). Да и сравнивать его с другими языками особо смысла нет, ибо нет и альтернатив.
                                                                                                                                +1
                                                                                                                                А мне C++0x нравится!

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

                                                                                                                                  Тот же thread_pool из примера — отличный класс, как раз то место, где мета политики важны и нужны. Уместность конкретного выбора политик, впрочем, трудно оценить в первом прочтении.

                                                                                                                                  В общем, -1, сообщению не хватает структурированности, попробуйте рефакторинг :)
                                                                                                                                    –1
                                                                                                                                    ООП головного мозга, не относящаяся напрямую к С++

                                                                                                                                    Не-ООП вермишели от прошлого кодера обошлись потерей 30% клиентов.
                                                                                                                                    FileScanner — у нас сканировал и память, и реестр, и папки, а еще глобальные настройки менял, в разных методах файла.

                                                                                                                                    Тот же thread_pool из примера — отличный класс

                                                                                                                                    1) Для изучения внутренностей ушло 2 дня, попутно изучил boost thread 2) Не понял, к чему эти мета-политики для такого функционала: задать константый размер пула, положить туда объект задачи (интерфейс ITask например а-ля C# 4.0), при завершении задачи, вызвать нотификатор, который обработает результат, pause/resume/stop для выполняющихся задач. => Последнее предложение, стандартными средствами не делается.
                                                                                                                                    3) Подключение хэдера <boost/thread_pool>, увеличивает время компиляции в разы.

                                                                                                                                    не хватает структурированности, попробуйте рефакторинг :)

                                                                                                                                    Спасибо, учтем. Первый топик :)
                                                                                                                                    +2
                                                                                                                                    для кого-нибудь, наверное, и пхп сложный язык.

                                                                                                                                    не вижу ничего плохого в шаблонах. самое главное — понимать, зачем это нужно конкретно тебе в конкретно этой задаче.

                                                                                                                                    ./anketa/json_field_lists.hpp:151:80: instantiated from ‘P fas::json::serializerT<fas::pattern::type_list_inst<L> >::unserialize_member(TC&, TF&, P, P, bool&) [with P = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >, TC = fas::pattern::type_list_inst<fas::pattern::type_list<anketa_fields::field_user_id, fas::pattern::type_list<anketa_fields::field_age, fas::pattern::type_list<anketa_fields::field_anketa_name, fas::pattern::type_list<anketa_fields::field_login, fas::pattern::type_list<anketa_fields::field_drink, fas::pattern::type_list<anketa_fields::field_sign, fas::pattern::type_list<anketa_fields::field_orientation, fas::pattern::type_list<anketa_fields::field_target, fas::pattern::type_list<anketa_fields::field_constitution, fas::pattern::type_list<anketa_fields::field_hairshead, fas::pattern::type_list<anketa_fields::field_marital, fas::pattern::type_list<anketa_fields::field_circumstance, fas::pattern::empty_type> > > > > > > > > > > > >, TF = fas::pattern::type_list_inst<anketa::fields>, L = anketa::fields]’
                                                                                                                                    ./anketa/json_field_lists.hpp:151:80: [ skipping 9 instantiation contexts ]


                                                                                                                                    > Зачем все эти шаблоны шаблонов.

                                                                                                                                    Читайте книги — источник знаний.
                                                                                                                                      +34
                                                                                                                                      господи, автор топика бы ещё яву посмотрел энтерпрайзную.

                                                                                                                                      You have a problem and decide to use Java.
                                                                                                                                      Now you have a ProblemFactory, ProblemFactoryConfigurationManager and problem/factory/config/production.xml
                                                                                                                                        +3
                                                                                                                                        это не язык, а отрыжки OOP, такое есть и на C++/C#
                                                                                                                                          +2
                                                                                                                                          у меня есть подозрение, что корни этой проблемы ведут к языку. на c++/c# я такого не видел.

                                                                                                                                          static.springsource.org/spring/docs/2.5.x/api/org/springframework/aop/framework/AbstractSingletonProxyFactoryBean.html

                                                                                                                                          впрочем, я могу и ошибиться. ведь кому-то может и понадобиться AbstractSingletonProxyFactoryBean.
                                                                                                                                            +2
                                                                                                                                            корни ведут скорее к энтерпрайзу, как говорится, положение обязывает

                                                                                                                                            впрочем, вместо этих всяких фабрик теперь @Inject
                                                                                                                                        0
                                                                                                                                        >>anketa_fields

                                                                                                                                        Очень хороший код, ага
                                                                                                                                          0
                                                                                                                                          очевидно же, что код плохой, ведь это сообщение об ошибке
                                                                                                                                          +16
                                                                                                                                          > не вижу ничего плохого в шаблонах.

                                                                                                                                          image
                                                                                                                                            –3
                                                                                                                                            Пример повседневной задачи, где вы применяли шаблоны шаблонов.
                                                                                                                                            Да что там, просто самостоятельно созданный шаблонный класс?
                                                                                                                                              +1
                                                                                                                                              вы так говорите, как будто вы мой начальник и платите мне зарплату и я по этой причине вам что-то должен. а я вам ничего не должен, и не нужно со мной говорить в таком тоне.
                                                                                                                                                0
                                                                                                                                                Пропустил «Приведите, если можно, пример...». Про тон — вам показалось. Это вопрос-ответ на
                                                                                                                                                > Зачем все эти шаблоны шаблонов.
                                                                                                                                                >>Читайте книги — источник знаний.
                                                                                                                                                +1
                                                                                                                                                vector<string> это, если я правильно понял вашу терминологию, шаблон шаблонов. Вам привести пример повседневной задачи, где используется vector<string> или вы сами?
                                                                                                                                                  0
                                                                                                                                                  Имеется ввиду, не библиотечный код, а ваш собственный. Например, мне нужно парсить бинарный файл с секциями. У каждой секции свой формат. Но одинаковые операции: считывания и распаковки. Вот распакованная секция, подавалась шаблонному параметру ParserClass, с перегруженным operator()( char *section ). Типы элементов, к-ые парсятся, тоже разные. Поэтому и класс с распарсенными данными, на выходе.
                                                                                                                                                  Больше умственных усилий, чем несколько раз продублировать код чтения и распаковки.
                                                                                                                                                  Про такие примеры я говорю. Что у вас есть задания, вы ищите закономерность и обобщаете ее, либо вширь (шаблоны), либо вглубь (наследование). Повседневное применение
                                                                                                                                                    0
                                                                                                                                                    Имеется ввиду, не библиотечный код, а ваш собственный.
                                                                                                                                                    В общем то шаблоны как раз и предназначены в основном для библиотек — вы пишете обобщенный класс/функцию, который/ая работает не пойми с чем, а пользователи потом заставляют его работать с тем, чем нужно. И да, мой собственный код часто бывает библиотечным, в смысле что приходится писать и куски библиотек иногда.
                                                                                                                                                      –1
                                                                                                                                                      Таким образом мы и имеем избыточный язык для библиотек. Я даже обобщу. Лучше если был бы С++ для библиотек, и С++ для решения задач.
                                                                                                                                                      Для первого — все, что ограничивает пользователя библиотеки + шаблоны. Те же спецификаторы доступа, const, абстрактные функции, explicit, friend. Для второго — NoRulesCPlusPlus. С одной оговоркой — код не падает во втором случае, от незнания библиотечных фич.
                                                                                                                                              +18
                                                                                                                                              Ня!
                                                                                                                                                +1
                                                                                                                                                Все ж дело личное — хочешь используй, не хочешь не используй.
                                                                                                                                                Несколько моих попыток побаловаться с др языками всегда приводили к ощущениям «и тут жмет» и «тут не хватает». Мб просто также банальная нехватка знаний этих прочих языков.
                                                                                                                                                А вообще всему свои задачи.
                                                                                                                                                  +40
                                                                                                                                                  Поэтому такие языки, как Python и Ruby завоевывают популярность, т.к. позволяют сосредоточиться на задаче, а не на средстве ее решения. Осталось подождать, пока они сравняются по скорости хотя бы с Java и жизнь станет немного счастливее.
                                                                                                                                                    –2
                                                                                                                                                    Сначала сосредотачиваешься на задаче, а потом месяц пытаешься обработать напильником оптимизировать узкие места, чтоб работало побыстрее.
                                                                                                                                                      –1
                                                                                                                                                      Мало что мешает на том же Си переписать эти самые узкие места.
                                                                                                                                                        0
                                                                                                                                                        Ключевое слово переписать.
                                                                                                                                                          0
                                                                                                                                                          Такая ли эта проблема? Цель — выкатить прототип, оптимизация узких мест будет после. Обычно это сотен пять строк из 50-70 тысяч; эти пять сотен и переписываются в тысячу на Си. Сие не есть очень трудозатрадно, даже в кайф по-своему.
                                                                                                                                                            –1
                                                                                                                                                            Да ну я на Python на самом деле не гоню. Мне он тоже нравится, хотя я знаю его очень слабо. Просто по скорости работы некоторых алгоритмов он не хило… эээм… отстаёт, скажем так. Ну это опять же, смотря что писать, верно.

                                                                                                                                                            С другой стороны, С++ мне никоим образом не мешает концентрироваться на задаче, а особенно те притянутые за уши «доводы», увековеченные письменным словом в данном топике. А коммент мой был к тому, что каждому языку отведено своё место.