Как стать автором
Обновить

Комментарии 534

Долой программирование!)
Или: Даёшь ассемблер в массы! :)
НЛО прилетело и опубликовало эту надпись здесь
Правильно Роботов на разработку!
Серьезному языку — серьезные задачи: драйверы и другое низкоуровневое ПО, критичное к производительности ПО и так далее.
Простую утилиту(надеюсь) на плюсах писать никто не будет.

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

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

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

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

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

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

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

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

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

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

Не бывает идеальных решений: в одном месте делаем проще, в другом становится сложнее.
НЛО прилетело и опубликовало эту надпись здесь
А 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 — макросы препроцессора, который в С активно используется именно потому что больше нечего использовать, а прятать копипасту нужно, и это я пропустил ту часть, которая выделяет под это все память.
Ещё забыли про повсеместно используемый void** :)
И вы правы, и ваш оппонент прав. Чтобы использовать Си в новом проекте нужны очень веские причины, о и чтобы пользоваться всей мощью Си++ нужны они же.
Смотря производительность чего. Производительность программиста таки поднимают, так как чем высокоуровневей язык, тем проще делать сложное.
Слава Богу, но драйвера, ПО для встраиваемых систем и прочее низкоуровневое пишут на С или Embedded C++.
Я простые утилиты пишу на C++. Мне он нравится, ничего не могу с собой поделать. Как правильно заметили ниже, никто не заставляет использовать все фичи.

Кстати, некоторые из перечисленных «камни преткновения» легко можно набросать и в «огороды» всяких там Джав и СиШлаков.
Пардон, правильно заметили выше :)
НЛО прилетело и опубликовало эту надпись здесь
На выходных контест был, и ярый адепт С++ в лице меня писал игру на (о боги!) Java о_О Прикинь.
Так знаешь, через пару часов Java мне показалась не таким уж плохим языком.
НЛО прилетело и опубликовало эту надпись здесь
Верно то, что это не проблема языка.
Дело, конечно, Ваше. Но! Применительно к лаконичности языка, Java превосходит С++, а C# превосходит Java, а Ruby… ну т.д. Возможно, авторы C++ грезили всемирной революцией и поспевая за развитием Java начали искать ему применение всё в большем количестве областей, добавляя к нему новые конструкции. Возможно! Но ведь получился уродец на костылях. Он, конечно, ходит. Но как?!
Применительно к лаконичности языка, Java превосходит С++

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

А если будут?

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

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

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

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

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

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

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

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

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

Как же он мусор из кучи собирает? Если он их сразу не трогает (не помечает как свободные), значит он трогает их потом.
В случае умных указателей оверхед на удаление велик при стандартном аллокаторе, который выдает память любого размера. В случае пула, который выдает одинаковые объекты, удалять действительно нужно все, но это удаление будет сводиться к той же пометке свободных блоков.
Если создавать дерево из пустого от листьев к корню, то удалений не будет вообще, обычно они так и разворачиваются. Если делать как-то по-другому, не понятно, почему счетчик будет медленнее.
НЛО прилетело и опубликовало эту надпись здесь
Собирает очень просто — вычисляет граф «живых» объектов, затем перемещает живые объекты так, что-бы они лежали последовательно друг за другом, уплотняя кучу.

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

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

У персистентного дерева добавление к корню бесплатно (в том числе от корню существующего дерева), и его очень удобно конструировать и повторно использовать таким образом. Частая замена, которая вызывает работу GC, какой-то странный вариант для языка с присваиваниями даже в многопоточной среде даже если GC охота использовать.
НЛО прилетело и опубликовало эту надпись здесь
Для толстых объектов есть отдельная куча. По факту это работает быстро, он ведь не делает это для всех объектов сразу

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

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

Конечно не девается, новый элемент начинает указывать на корень старого дерева, поэтому его так быстро создать рекурсивной функцией и пересобирать, зная, что большая часть элементов останется на месте. Иначе толку от него — гордиться отсутствием присваивания.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
«Уже давно» — это сколько лет?
17 лет, с момента стандартизации STL в 1994-м году.
В 1995-6 упоминания о нем не видел в продававшихся тогда книгах :(
shared_ptr и не было до буста. Но вместе с STL появился auto_ptr (точнее, он появился раньше в библиотеках SGI но не суть), который как бы тоже смарт-указатель.
По поводу shared_ptr ответили ниже, хочу сказать о другом.
Книги по С++ из 90-х — это ужас. Как и 80% книг, которые продаются сейчас, которые переиздаются без именений по многу лет. 40% страниц описывается С (с динамическими массивами на указателях), еще 40% — основы синтаксиса ООП, и махонькая глава, посвященная STL, что мол есть вектор, а зачем он есть — не понятно.
В итоге и считается нормой, что массивы в прикладном коде передаются из функции по указателям (с соответствующим выделением памяти вне функции) вместо того, чтобы возвращать std::vector через return и много других подобных примеров.
Потом человек читает Александреску и его бросает в другую крайность. Писать на C++ так же, как на C# — без маблонной магии, но и без сишных открытых выделений памяти и велосипедов, почему-то западло.
Ну в принципе да, примерно такого уровня и читал книги. Ну и F1 :)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Что из этого читабельнее еще большой вопрос. Это очень субъективная вещь — мне лично сложно _не_ думать о том где параметр передается по ссылке, где по значению, какой здесь класс и неймспейс и прочее прочее. Думаю я не один такой.
Да ну пишите всё в хедерах, ради бога… Не будет Вам никаких ::
А вот const после метода очень даже не лишний — сразу понятно, есть ли у метода… кхм… «побочные эффекты».
НЛО прилетело и опубликовало эту надпись здесь
Потому что такая модель комплияции :) Ну и это просто удобно — интерфейс в одном месте, реализация в другом. Хочешь окинуть взглядом класс — посмотрел хедер. Хочешь покопаться в деталях, полез в реализацию. Как-то это, естественнее что-ли. Когда после С / С++ начинаешь писать на языках где нет хедеров начинается страшная ломка. Так что это, имхо, дело привычки.
НЛО прилетело и опубликовало эту надпись здесь
Если нужно окинуть взглядом класс, можно хоткеем скрыть все, кроме имен методов. Да здравствует IDE 21-ого века. :)
против таких ломок есть приёмок: docstring на уровне синтаксиса и perldoc/pydoc.

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

И лично мне эта «дырявая и ненадежная система» много раз экономила время выдавая ошибки на этапе компиляции, а не где-то в рантайме с опозданием на Эн (Эм, если Эн мало) операций (вызовов, секунд, итераций — нужное подчеркнуть).
НЛО прилетело и опубликовало эту надпись здесь
grep const_cast (это, кстати, ответ на вопрос, почему эти вещи называются так длинно)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Гарантии, что никто нигде не поменяет значение «случайно».
«Никто» — это вы сами, а «нигде» — это в теле метода, который вы сами ниже пишите и который в ваших же интересах написать простым и обозримым? Вам не кажется, что что-то здесь не так? :) То же касается и мусорных m_. Программист, не могущий запомнить области видимости и контест переменных в коде с которым работает — профессионально некомпетентен.
Даже если вы не допустите таких ошибок и вам это не нужно, вы сэкономите время мейнтейнерам. А если вы считаете что мейнтейнить должны только профессиональные и компетентные программисты то подумайте о том, что каждый компетентный программист когда-то был некомпетентным.
В качестве мистера «никто» может выступить программист, который влез в этот код, когда вы уже год как уволились. Есть метод, у метода есть контракт — метод не изменяет переданный в него объект. Это значит, что при вызове этого метода мне не нужно блокировать объект на запись, если идёт работа в многопоточном окружении.

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

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

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

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

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

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

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
>«Никто» — это вы сами, а «нигде» — это в теле метода, который вы сами ниже пишите и который в ваших же интересах написать простым и обозримым? Вам не кажется, что что-то здесь не так? :) То же касается и мусорных m_. Программист, не могущий запомнить области видимости и контест переменных в коде с которым работает — профессионально некомпетентен.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ай, перестаньте. Я предыдущие 8 лет работал над проектов в котором в отдельные моменты времени работало и по 30 человек и QA и ручные тесты и бюджет и тд. Это всё не повод писать говногод и покрывать его мусором. А первоначально проект достался вообще в таком виде, что мама-не-горюй — несколько поколений программистов училось на нём писать на новом для них языке, бизнес-логика была размазана по .jsp-шкам вперемешку с HTML разметкой, одних только обёрток для работы с БД было четыре или пять :). Если бы там были ещё и говнопрефиксы…
НЛО прилетело и опубликовало эту надпись здесь
да, это охуенно.

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

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

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

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


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

А зачем про это «думать»? После нескольких лет это идёт на полном автомате.
НЛО прилетело и опубликовало эту надпись здесь
Иногда нужны, иногда не нужны, в зависимости от задачи.
И на полном автомате идёт именно нужная форма.
class DetectionManager {

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



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

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

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

The Dark Side of C++
C++ FQA Lite
НЛО прилетело и опубликовало эту надпись здесь
> Давайте, для интереса, напишем решение этой задачи: вы на c#, я на c++ и сравним результаты. :)

Давайте.

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

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

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

Но только про C++ его так много.
НЛО прилетело и опубликовало эту надпись здесь
File.ReadAllLines("test.txt")
    .Where(line => line.Split(' ').Length > 3)
    .OrderBy(s => s)
    .Run(Console.WriteLine);
НЛО прилетело и опубликовало эту надпись здесь
Да, на Питоне будет что-то типа такого:
lines = open('test.txt').readlines()
for line in sorted( filter(lambda x: len(x.split(' ')) > 3, lines) ) :
	print line.rstrip('\n')


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

Кстати, есть другие варианты? Я с Питоном знаком не то чтобы очень плотно…
А, ну да, чего это я:
from sys import stdout

lines = open('test.txt').readlines()
stdout.writelines( sorted( filter(lambda x: len(x.split(' ')) > 3, lines) ) )

Разбито на 2 строки, опять же, чтобы влезло по ширине.
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)
А зачем делать
with open('test.txt') as lines

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

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

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

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

Вместо «open('test.txt')» должно быть «open('test.txt').readlines()», что даёт ещё +12 символов.
А _.count(' ') считает просто количество пробелов?
Да, только считает… смысл искать пробелы и делить для этого список, если можно только найти пробелы?
Например, если идет несколько пробелов подряд.
С одной стороны, да, косяк ))) с другой split(" ") тогда тоже даст неверные результаты, а вот split без параметров — да, тогда действительно лучший вариант )
С использованием 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, а вам нужно вывести его в текущей локали.
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. Т.е. код выше — просто демонстрация.
Понятно, спасибо.

Для моего варианта изменится одна строчка:
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;


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

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

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

Можно задачу без библиотек. Например: вернуть из первой функции другую функцию, замыкающую по ссылке локальную переменную первой функции.
Это не задача, а решение
Хорошо, пусть решение. Так вы можете предоставить код решения на 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
Такие замыкания в паре с мутабельной лямбдой используют в Scheme для имитации объектов. Зачем это в С++, если можно вернуть объект?
ideone.com/qnbrm
> Такие замыкания в паре с мутабельной лямбдой используют в Scheme для имитации объектов.

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

> ideone.com/qnbrm

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

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

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

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

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

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

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

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

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

Ерунда. Зачем мне передавать объект с состоянием, если я хочу это состояние скрыть от пользователя? Получится объект с одной функцией и недоступным пользователю состоянием. Так почему бы сразу не вернуть одну лишь функцию, зачем плодить сущности?
Я прекрасно знаю, как подобный код пишется на 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-методы можно не лочить в многопоточном приложении, например.
Изменяемость состояния псевдообъекта на замыкании не понятна, будь добр смотри в исходники.
> Тогда зачем это спрашивать у меня, нужно самому писать и говорить так и так, а не троллить

Я никого не тянул за язык, просто 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;
}
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 и спокойно меняем захваченное значение ибо оно внутри объекта, реализующего лямбду.
> и спокойно меняем захваченное значение ибо оно внутри объекта, реализующего лямбду.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Какая разница, есть ли тута схемщики. Я имел в виду слова (емнип) Нормана Адамса «Objects are a poor man's closures», которые считал достаточно известными.
> И да, использованная здесь 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 Мб.
> просто предкомпилированные пользовательские библиотеки весят от 200 Мб
Если мне не изменяет память, там не просто dll'ки. Там еще вся документация (в моем archlinux это пакет на 141 мегабайт), все утилитки типа дизайнера, сборки библиотек для отладки, демонстрационные примеры. Нет только IDE.
Библиотеки Qt весят 31 мегабайт. Хотите — поставьте себе в системе Qt и не парьтесь.

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

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

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

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

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

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

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

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

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

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

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

Да нет, просто опасался получить решение в одну строку вида superlib::do_some_magic(), где функция берётся из какой-то хитрой никому не известной специализированной библиотеки. А Qt ок, почему нет.
Тут что-то функциональщиной больше попахивает. На Haskell тоже можно в одну строку всё решение записать, но дело не в этом. Вряд ли сейчас на С++ невозможно реализовать нечто подобное. Просто в .NET Framework уже много готового.
std::wstring?
НЛО прилетело и опубликовало эту надпись здесь
Для юникода есть ICU
НЛО прилетело и опубликовало эту надпись здесь
Да, действительно. Извиняюсь.
Есть еще std::locale и иже с ним.
В С++0x добавили unicode-строки вроде ж, да?
Ну, то же, что у тебя, можно и чуть покороче записать в принципе. Что-то из серии:
#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;
}


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

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

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

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

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

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

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

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

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

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

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

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

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

./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 ]


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

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

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

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

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

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

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

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

С другой стороны, С++ мне никоим образом не мешает концентрироваться на задаче, а особенно те притянутые за уши «доводы», увековеченные письменным словом в данном топике. А коммент мой был к тому, что каждому языку отведено своё место.
Я до Питона (последние 4 года) пару лет писал на плюсах, перелопатил кучу литературы, от Страуструпа до Александресу через всякие гайды. Qt до сих пор забыть не могу, как лучший фреймворк для интерфейсов. Но и MFC тоже помню.

Так вот.

А надо ли это было все..? Это ведь не так сложно. Сравнить хотя бы Кернигана-Ричи с их Си, и талмуды Страуструпа.

У меня есть теория, что плюсы — это как письменная речь автора языка; те же сложности на ровном месте, та же многословность, те же неозвученные подводные камни.
Если честно, я Страуструпа не читал. Каюсь, ага. Но в принципе литературы перечитал немало конечно. Вот только не жалею, ибо знал, на что шёл.
Вы лучше почитайте про разработку парсеров для языка :) Если универ был профильный, то знаете точно, в чем проблема с анализом контекст-зависимого языка :) Это ведь не только пользователи языка жалуются; не случайно компиляторов и, тем более, поверхностных парсеров С++ в мире кот наплакал.
Ну, я на этом деле не то что бы собаку съел, но немного понадкусывал уж точно. Проблема с парсингом С++ наиболее отчётливо видна в недо-IDE, потому что по сравнению с фичами, которые в них есть для других языков… Ну в общем, Вы знаете :(
Кстати, в тему. Я Емаксом в работе каждый день пользуюсь уже лет шесть.

Так вот, для этого редактора некий программист создал один из самых совершенных парсеров Си/C++; и побоку культура редактора, подразумевающая минималистичный подход к написанию кода. На Лиспе! Даже не на лиспе, а подмножестве его — Emacs Lisp!

Бывают же люди…
Разработку IDE с их фичами вроде проверки синтаксиса на лету для C++ останавливает шаблонизатор и механизм заголовков, который требует от компилятора обработки огромных объёмов кода.
Сюда же мой любимый Clojure, который в узких местах можно заменить джавой (это в самых экстремальных случаях). Плюс грядущий Clojure 1.3 обещает быть очень быстрым.
в таком случае надо идти на D language. может сообщество разрастётся.
Останавливает отсутствие нормальной среды разработки уровня Intellij Idea =(.
А вы без Intellij уже код на приличном языке писать не сможете, да? :))

Вообще говоря, парсить толково С++ тоже крайне мало IDE умеет. Даже команда Visual Studio с ее безбрежным бюджетом сию задачу, прям скажем, с оговорками выполнила.
Смогу хоть в ноутпаде, просто долго ковыряться придётся.
А чем там ковыряться?

Я всю жизнь с Емаксом пишу; и на Хаскелле, и на Питоне, и на Си, и на СиПлюсПлюс; и на Эрланге. Думаю, и с Ди бы справился :)

Спорный это повод язык интересный не изучить — отсутствие «удлинителей рук» :) Тем более что D значительно лаконичней Java.
cedet/semantic парсит c++? без эвристик и AI? :)
Парсит, сам видел :) Не без хитростей и засад, но парсит.

Вообще, изумляюсь даже не упорности — самоотверженности автора CEDET. Шесть лет жизни в Емаксе, и шесть лет вижу коммиты в CEDET.
¿Не пробовали скормить примеры из «dark sdie of c++»:
template struct Loop { Loop<T*> operator->(); };
Loop i, j = i->hooray

struct a{typedef int foo;};struct a1:a{};struct a2:a{};
#define X(b,a) struct a##1:b##1,b##2{};struct a##2:b##1,b##2{};
X(a,b)X(b,c)X(c,d)X(d,e)X(e,f)X(f,g)X(g,h)X(h,i)X(i,j)X(j,k)X(k,l)
X(l,m)X(m,n) n1::foo main(){}


(сам я его снёс - оно питон не понимает)
Немного оффтоп. Увидел в «Dark side of C++»: Can’t call virtual member functions from constructor. Вроде все нормально работает.

#include using namespace std;

class A
{
public:
virtual void Call() { cout << "A\n"; };
};

class B : public A
{

public:
B() { Call(); }
virtual void Call() { cout << "B\n"; }
};

int main()
{
B b;
return 0;
}


Выводится на экран "B".
Или я что-то не так понял?
Спасибо с ответ.
P.S.: За ссылку на сервис отдельная благодарность.
Я использую Geany и иногда Code::Blocks, мне нравится.
НЛО прилетело и опубликовало эту надпись здесь
в том то и дело что начиная описывать алгоритм ты натыкаешься на то что описываешь уже не сам алгоритм, а обходишь ямы языка.
Автор же приводил примеры — const/mutable, get/set, throw()… все это выжимает из тебя кучу времени и душевных сил, в то время как написание прототипа из десятка функций в одном файле ( просто чтоб работало ) заняло полчаса-час.
НЛО прилетело и опубликовало эту надпись здесь
Подход «рисуем приложение мышкой» как-то тоже особого распространения не получил, ограничился, вроде как, созданием интерфейсов в редакторах, а логика пишется по старинке. Правда могу ошибаться, периодически только PyQt пользуюсь для одноразовых утилиток, может в мэйнстриме сейчас всё по другому.
НЛО прилетело и опубликовало эту надпись здесь
Ну, тот же MS Access (прости, господи), позволяет создавать приложения типа «нажми на кнопку — получишь результат» в полностью визуальном режиме, причём в самом популярной, наверное, для бизнеса области — учёт и анализ. Другое дело, что шаг влево, шаг вправо от «захордкоженных» MS сценариев и приходится писать свои обработчики, валидаторы, источники данных и т. п. ручками.
НЛО прилетело и опубликовало эту надпись здесь
Вы «настраивали» :) более-менее серьёзные приложения в Access? Можно настроить визуально не только таблицы, связи между ними, запросы (визуально работать с SQL), отчёты и формы, но и кое-какую логику управления типа «при нажатии этой кнопки формы вывести отчёт такой-то, при нажатии той — открыть форму, при нажатии третьей — запустить макрос». В принципе морду к SQL БД создать можно было довольно функциональную и даже оперирующую терминами предметной области (пускай и торчащими отовсюду следами реляционной модели и самого Акцесса), но на основе предопределенных таблиц, запросов, форм и отчётов.

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

Полностью согласен, и если визуальное (декларативно-интерактивное в общем случае, наверное) создание нового типа сущности, создание, представление и редактирование экземпляров этого типа без кодирования худо-бедно решено (в том же 1С, или Drupal), то вот с поведением, да, никакого прогресса не наблюдается со времён DOS — или стандартные обработчики событий (хорошо если параметризуемые) или пиши код.

НЛО прилетело и опубликовало эту надпись здесь
const рулит, mutable — возможность, а не яма, throw-спецификации теперь deprecated вроде.
что скажете на
friend
спецификаторы, улучшают инкапсуляцию. — Б. Страуструп.

То же могу сказать и про спецификаторы доступа при наследовании.
По большому счету, добрая доля плюсовых гуру-фичей, нужна при написании библиотек.
Но все самое лучшее ПО написано на С++
На C =)
на Objective-C 0_0
Кстати, когда требуется, допустим, передать NSRange в обзервер я конвертирую его в NSString(sic!) и потом в обсервере обратно в NSRange. По хорошему нужно бы для таких случаев иметь класс-обертку, но это гораздо больше работы и еще один мини-класс-утилита, решающий задачу, непонятно почему нерешенную, авторами стандартного фреймворка.
-[NSValue valueWithRange:]
Документация же есть
Спасибо, полезный класс.
Документацией я пользуюсь регулярно, но както этот класс пропустил, поэтому юзал NSStringFromRange
а в objc есть хоть какой-то аналог boost::shared_ptr? тут народ на работе ерундой занимается, вызывают руками retain'ы/release'ы, сами же в них и путаются
В ObjC это С, поэтому там не может быть RAII. Можно, конечно, писать на ObjC++, но обычно обходятся без этого. В ObjC другая парадигма управления временем жизни объектов, читайте про NSAutoreleasePool и обязательно Memory Management Policy — там описано, когда нужно вызывать retain и release, а когда нет.

Cейчас в Cocoa вроде даже GC прикрутили, но я не разбирался, давно не пишу на ObjC.
… ответил фанат Linux-а фанату Qt.
Common Lisp — вот красивая панацея! Делаете себе с помощью макросов (настоящих!) именно то, что надо
Ага, макросы — отличный способ расширить язык и не дать заказчику сменить исполнителя, уйти на поддержку в другую компанию. Как, впрочем, и сам Common Lisp.
Извините, но аргумент дурацкий. Расширения языка должно улучшить качество кода и в том числе читабельность и поддерживаемость. Если этого не удалось достичь, то проблема в программисте, а не в макросах таковых.

ЗЫ. Думается, крутость макросов лиспа — не более чем миф среди тех, кто только слышал про лисп, но никогда на нем не писал. Я на лиспе не писал, но видел реальный код. Макросы там довольно редки.
В идеально мире это так, но на деле макрос в чужом коде(я сейчас не про лисп а в общем) детектируется глазами очень сложно, он может выдавать себя за другую конструкцию языка(функция, опкод, оператор,...), не являясь таковой. В итоге: сначала нужно понять, что это макрос, потом найти его объявление, потом разобраться как он работает.Та-же лабуда с перегрузкой операторов.
Понятно, что есть good/bad-pratice, но этого не мешает плохому коду появляться на свет.
Есть языки, которые все критикуют, и языки, на которых никто не пишет.
зачёт! :-)
НЛО прилетело и опубликовало эту надпись здесь
… и Питон.
Для него «и того, и другого» выполняются? ;)
Если бы для него выполнялось и то и другое, он входил бы и в ту и в другую группу и не требовал бы отдельного упоминания. Ваше Кэп.
Не люблю такой стиль изложения, как у автора. Для блога он ещё приемлим, но для серёзных статей… становится просто трудно читать, иногда перечитываешь предложение заново.

А C++ вовсе не избыточен. Скорее всего вы просто используете фичи языка в задачах, для которых они не предназначены. А следовать «правилам хорошего тона» нужно не слепо, а с умом. К примеру, тот же goto стараются избегать для улучшения читабельности. Если в данном конкретном случае goto не ухудшает читабельность, почему бы его не использовать?
А ещё C++ «закаляет» программиста, в то время как языки вроде Python, Ruby, PHP дают ему расслабится — что и приводит к быдлокоду на раннем этапе развития. Это всё равно, что в школах вождения учить водителей на дорогих машинах с гидроусилителями руля.
> А ещё C++ «закаляет» программиста, в то время как языки вроде Python, Ruby, PHP дают ему расслабится — что и приводит к быдлокоду на раннем этапе развития.

Бред. Быдлокода на С++ на раннем этапе никак не меньше.
Согласен, тут я неправ.
НЛО прилетело и опубликовало эту надпись здесь
Можно закалиться и на простых языках, если будет кому ревьюить.
Закаляться надо дома в ванной. На работе обычно ожидают решения задач.
НЛО прилетело и опубликовало эту надпись здесь
Вывод: надо начинать писать сначала в машкодах, потом на ассемблере, потом на Си, потом на Си++ и после того как сильно закалился можно и расслабиться с динамическими?
Признаться, если исключить из цепочки С++ (не уверен, что вообще нужен), на выходе получится программист сразу после качественного профильного универа :-D
На выходе получится я после второго курса профильного универа :), правда были ещё BASIC, FORTRAN, FORTH, dBase и Pascal.
Ну, если про себя… Я учился на энергетика, но в силу семейных обстоятельств и личной тяги к компутерному делу до третьего курса прошелся от asm через Lisp к C++, на которых и застрял на пару лет, пока не стал веб-девом с Питоном :)

Особенно же полезны были именно плюсы и Lisp. Первые помогли с пониманием объектностей всяких, Лисп же — функциональных радостей.
Ну для меня перед переходом на веб-дев с PHP больше всего были полезны asm и C для понимания принципов работы софта под полноценными ОС, и «Си с классами» для ООП (как мне его не хватало на PHP3). Функциональные радости как-то не осилил даже в JS, то есть консольные учебные приложения «из головы» пишешь, а тот же «Hello %username%» в вебе хотя бы через CGI — затык.

Но вообще я хотел сказать, что цепочки выше, имхо, явно недостаточно для того, чтобы считаться программистом — эникейщик, продвинутый пользователь, может кодер, но не программист :(
Ну… Есть же еще слабопреподаваемые вещи вроде стиля, вкуса, умения видеть систему top-down, хороших практик языков и темных их мест.

Это если не считать алгоритмов; базовых теорий; численных методов и прочего.

А фупнкциональное дело понять можно из общения с какими-нибудь Lisp и Хаскелл. Сами-то языки можно и не использовать, пожалуй, но вот понимать замыкания, лямбда-выражения и разного рода fold, map, apply — надо бы. Код становится лаконичней на порядок.

Я, правда, не знаю, как с этим в Php, но в Питоне есть целая группа встроенных средств и модулей под это дело.

В общем, голосую за Си, как базовый язык для понимания всего и вся :)
Согласен, лучше исключить С++, но в конце не обязательно динамический язык. Главное что действительно высокоуровневый.
Только C++ пропустить в этой последовательности, и какой-нибудь функциональщины добавить можно. Ну или просто пройтись по C++ как по C с классами, в детали не вдаваясь. Блин, как я жалею, что на него несколько лет убил, все эти тонкости изучая, которые нигде, кроме C++ не нужны, с какими-то трюками и тонкостями реализации разбираясь вместо разбора алгоритмов и приобретения полезных привычек (вроде KISS, DRY и тестов).
>он экономически не выгоден — два
Мощный такой задвигон, как для языка на котором написано куча ОС, офисных пакетов, граф.редакторов, игр и прочей фигни, приносящей по пару сот лимонов производителю каждый год. Предложите на чем это переписать, так чтоб экономически выгоднее было?

А вообще забавно читать такую статью автора, чей ник содержит cpp. :)
> Предложите на чем это переписать, так чтоб экономически выгоднее было?

А еще абсурднее требования выдвигать не? То, что на С++ написана тонна legacy-кода не говорит о том, что:
— C++ экономически выгоден
— это все надо переписать
НЛО прилетело и опубликовало эту надпись здесь
Сравнивать надо одинаковое с одинаковым.

Например тут есть про С++ и Erlang. Человек за полтора-два года в одиночку сделал видео-стриминг сервер на Erlang'е, который догнал и по некоторым параметрам уже обогнал сервера, которые ковыряют енсколько человек на традиционных языках.

Здесь 37signals переписали все с С на Erlang и получили выигрыш.

И т.п.

Вот что надо сравнивать, а не выдавать смехотворные заявления типа «а вот есть ОС, давайте ка ее перепишем»
НЛО прилетело и опубликовало эту надпись здесь
я как то пытался найти русскую литературу о нем, язык вроде не новый, а русской литературы я нашел 0,00 :(
В одном из журналов-][ кажется второй половины 2008 года, были статьи о нем.
> Почему не сравнить возможность написания ОС на разных языках?

Давайте сравним. Осталось найти проекты, реализующие ОСи не на С/С++
На асме есть )
Кстати, да :)
Ну и опять-таки давайте вернемся к понятию экономической выгоды. Много народу умеет программить на Erlang на хорошем уровне? Единицы. А значит платить такому программеру Вы будете в разы больше. При том, что чудес в духе «сразу стало в тыщщу раз круче» не получите, это все максимализм и вера в чудеса.
> Ну и опять-таки давайте вернемся к понятию экономической выгоды. Много народу умеет программить на Erlang на хорошем уровне?

2 недели на обучение и программист начинает писать production-ready код. Недостижимо для С++.

> А значит платить такому программеру Вы будете в разы больше.

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

> При том, что чудес в духе «сразу стало в тыщщу раз круче» не получите, это все максимализм и вера в чудеса.

Сразу не станет, но в несколько раз лучше станет — это точно. Для определенного круга задач, естественно.
>2 недели на обучение и программист начинает писать production-ready код
Хорошо вам, в Хогвартсе, с вашими методиками обучения. А в нашем-то, реальном мире программеры по пару лет учаться в универах и еще пару лет на позициях джуниоров.
Добавить к этому стаж программиста на пол ставки в том же университете, что учишься, когда в «обязанности» входит обучение бухгалтерии пользоваться MS Word. А иначе никак — на всех работах стаж требуют.
> Хорошо вам, в Хогвартсе, с вашими методиками обучения.

Хорошо в любом месте, где есть мозги и нет нытиков.

> А в нашем-то, реальном мире программеры по пару лет учаться в универах и еще пару лет на позициях джуниоров.

Угу. Особенно это заявление смотрится в контексте ветки про С++ :-\

Программист не знакомый с Erlang'ом через 2 недели пишет продакн код на Erlang'е. Потому что с одной стороны Erlang в разы проще, чем С++ (по синтаксису он вообще примитивен), а сдругой позволяет выражать сложные понятия опять же в разы проще, чем С++.
>Хорошо в любом месте, где есть мозги и нет нытиков.
Я апплодирую стоя Вашему умению рубить с плеча. Конкретно в этом месте мне вспомнился эпизод с Ганнибалом Лектором, где он мозги жарил и не ныл. Во хорошо там было.

Угу. А то, что за любым мало-мальски важным алгоритмом или фреймворком этот самый программист побежит либо обратно проситься в нору к С++, либо сядет писать её с нуля на своем любимом Ерланге, который конечно круче С++ в 10 раз и поэтому написание фреймворка займет у него не 200 человеко-лет, а всего 20?
>2 недели на обучение

самообучение или под руководством опытного наставника?
На самообучение может понадобиться целых 3 недели.
Эх, рано я забросил — света в конце тоннеля не увидел :(
> Например тут есть про С++ и Erlang. Человек за полтора-два года в одиночку сделал видео-стриминг сервер на Erlang'е

А потом начали куске на Це переписывать: lionet.livejournal.com/84884.html
=))
быстро построил «гипсовый» прототип и начал его «отливать в металле» :)
Быстро построил систему, которая обслуживает миллионы сообщений в день, а потом мааааалюсенький и самый тупой кусочек, где нужна только скорость без логики, переписали на С.
Не куски, а ровно одну часть — сервер. Тут я и не спорю, что С (а не на С++, кстати) для этого подходит более, чем.

Потому что lionet.livejournal.com/84884.html?thread=2371732#t2371732

> А что остается на Эрланге?

Тонна всего. Этот сишный сервер — специализированный акселератор. Берёт очень маленькую часть функциональности, и делает её очень быстро.


Ну и тут: lionet.livejournal.com/84884.html?thread=2376084#t2376084

> Кстати да, вроде говорил что узкие места на OCaml-е пишете… А тут C вдруг.

Это исключение, потому что очень уж маленький scope. Если бы нужно было внесколькером разрабатывать, или нетривиальности делать — то только OCaml.


Что полностью соответсвует тому, что я где-то рядом написал: критические по скорости участки кода переписываем на С/С++. Все остальное на любом другом языке.
Что значит на любом? Эрланг далеко не любой язык, он сделан под это.
CUDA и C++ AMP тоже легаси? Да пусть легаси, легаси это не только старый софт (принципиально нового для десктопа в принципе не так много), но и библиотеки.
> Что значит на любом? Эрланг далеко не любой язык, он сделан под это.

Это значит на любом другом, а не на С/С++. На любом другом, подходящим под задачу.

> CUDA и C++ AMP тоже легаси?

я где-то рядом написал: критические по скорости участки кода переписываем на С/С++. Все остальное на любом другом языке.


> Да пусть легаси, легаси это не только старый софт (принципиально нового для десктопа в принципе не так много), но и библиотеки.

И? Это что-то меняет?
я где-то рядом написал: критические по скорости участки кода переписываем на С/С++. Все остальное на любом другом языке.

Я спрашивал не о том, что мне на чем писать.
Вы говорите о легаси. CUDA появилась не так давно. Ее развитие — это в том числе появление таких фич С++, как шаблоны и перегрузки операторов, библиотеки thrust. Шаблоны на GPU очень помогают сокращать код, избавляя от ветвлений без копипасты, а использование любого управляемого языка никаких преимуществ по сравнению с pure c не даст. Через 10 лет будет куча легаси, и в этом, видимо, С++ будет виноват.
И? Это что-то меняет?

Да
> Я спрашивал не о том, что мне на чем писать.
> Вы говорите о легаси. CUDA появилась не так давно.

Блин. Я говорю НЕ ТОЛЬКО о легаси.

критические по скорости участки кода переписываем на С/С++.


Это как раз подходит к CUDA

> Ее развитие — это в том числе появление таких фич С++, как шаблоны и перегрузки операторов, библиотеки thrust.

Эти фичи никакого отношения не имеют ни к развитию CUDA ни к самой CUDA.

> Шаблоны на GPU очень помогают сокращать код, избавляя от ветвлений без копипасты

Вы сами поняли, что написали?
Эти фичи никакого отношения не имеют ни к развитию CUDA ни к самой CUDA.

Ок.
То есть вы всерьез считаете, что появление в С++ шаблонов, перегрузки операторов влияют на развитие CUDA?
Где я писал о появлении чего в С++?
Появление в CUDA шаблонов и перегрузки операторов определенно влияет на развитие CUDA. Nvidia взяла на себя затраты на реализацию всего этого, не оставив чисто CUDA C, потому что это нужно и удобно, а не потому что кто-то заставляет nvidia этим заниматься из-за того, что у него на gpu полно наследства.
> Появление в CUDA шаблонов и перегрузки операторов определенно влияет на развитие CUDA.

А, неправильно прочитал. Мои извинения.

> Nvidia взяла на себя затраты на реализацию всего этого, не оставив чисто CUDA C, потому что это нужно и удобно, а не потому что кто-то заставляет nvidia этим заниматься из-за того, что у него на gpu полно наследства.

Боюсь, NVidia пошла на поводу у таких вот радетелей за С++ любой ценой. Хуже языка для реализации многопоточности и разработки вообще представить себе сложно.

Осталось понять вот это: «Шаблоны на GPU очень помогают сокращать код, избавляя от ветвлений без копипасты»
Боюсь, NVidia пошла на поводу у таких вот радетелей за С++ любой ценой.

Каких — таких? Легаси на CUDA не было, откуда они взялись. Может, потому что С++ — хороший язык?
Я понял логику. Пишут на С++ потому что легаси. Пишут новое — радетели значит заставляют.
Хуже языка для реализации многопоточности и разработки вообще представить себе сложно.

Какие претензии к С++, кроме предвзятости? Какие альтернативы?
Осталось понять вот это: «Шаблоны на GPU очень помогают сокращать код, избавляя от ветвлений без копипасты»

Есть у GPU-функции входящий const параметр, который проверяется в одном единственном if где-то внутри цикла. Например, вызывать дополнительный алгоритм по улучшению точности, или нет. Естественно, совсем не охота, чтобы этот if проверялся каждый раз внутри этого цикла. Можно сделать 2 версии функции, скопипастив их целиком с условием и без соответственно. А можно сделать шаблонную функцию, параметризованную стратегией, которая запускает код или нет в зависимости от того, какой функцией она параметризована. А можно собрать функцию из кучи таких параметров. И чтобы host и device код выглядел одинаково.
> Каких — таких? Легаси на CUDA не было, откуда они взялись. Может, потому что С++ — хороший язык?
> Я понял логику. Пишут на С++ потому что легаси. Пишут новое — радетели значит заставляют.

Начали они с С, напомню. Против С я ничего не имею.

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

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

> Какие претензии к С++, кроме предвзятости? Какие альтернативы?

Какая предвзятость? Это объективно. Достаточно почитать какой-нибудь C++ FQA, чтобы все стало на место.

Помимо прочего мы же говорим про параллельность вычислений, нет?

Ну и дополнительно: у С++ нет ни единого средства, способствующего нормальному распараллеливанию программ. Начиная отсутсвием нормальных библиотек для параллелизации и заканчивая сложностью написания на нем non-shared state.

> А можно сделать шаблонную функцию, параметризованную стратегией, которая запускает код или нет в зависимости от того, какой функцией она параметризована.

Звиздец. И это называется удобным и помогающим????

Это разруливается банальным паттерн-матчингом и ФВП (читать тут для понимания). И параллелизм получается (почти) бесплатно.

Модель параллелизма в CUDA не взята откуда-то объективно, она взята с потолка, потому что в C++ FQA об этом не написали, а разбираться самому вломы, так как объективное мнение уже составлено. Особенно радует предложение по поводу ФВП и почему-то паттерн-матчинга на ядре GPU, бесплатного притом.
С++ подходит единственный из высокоуровневых языков подходит для CUDA, потому что он не завязан на GC. Всякие DSL а-ля упомянутого здесь DSL для C# по функционалу недалеко от CUDA С ушли, то же С другим синтаксисом. Использовать один и тот же код для host/device нереально. Но зачем об этом рассуждать, если объективно С++ — говно, потому что динамические языки — круто. Ок.
> Особенно радует предложение по поводу ФВП и почему-то паттерн-матчинга на ядре GPU, бесплатного притом.

> Особенно радует предложение по поводу ФВП и почему-то паттерн-матчинга на ядре GPU, бесплатного притом.

Я понимаю, что читать простые предложения вы неспособны, но все же.

Нет такого понятия, как паттерн-матчинг на GPU. Паттерн-матчинг — это свойство языка программирования.

Описываемая вами «проблема» с параметрами и стратегиями решается в языке с ФВП и паттерн-матчингом на одном дыхании. В частности, в отсутствие необходимости городить, по сути, кодогенерацию на все случаи жизни. В С/С++ и то и другое отсутсвует. Ссылку вы, видать, не осилили. Ну что ж. Бывает

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

> С++ подходит единственный из высокоуровневых языков подходит для CUDA, потому что он не завязан на GC

Причем тут GC к CUDA? Вообще не при чем. Во-первых GC от GC отличается. Тот же Erlang прекрасно подходит для CUDA. Но прдлагать вам почитать про GC Erlang'а я вам даже предлагать не буду, все равно не прочитаете.

> Использовать один и тот же код для host/device нереально

Что бы вы под этим не подразумевали :-\

> Но зачем об этом рассуждать, если объективно С++ — говно, потому что динамические языки — круто.

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

Так же не имею ни малейшего желания говорить с человеком, перевирающим мои слова.

Всего доброго
Уйти после таких заявлений о CUDA — это вовремя. Я ведь не тянул за язык по поводу этого всего.
Паттерн-матчинг — это ветвление. Объяснить, что такое ветвление на GPU? Ветвление на GPU — это очень плохо. ФВП — это указатель. Я так и if зарядить могу, но почему не хочу я объяснил выше.
Параллелизм из учебников по «1000 процессов на 1 CPU» отличается от «1 программа на 32 GPU» поэтому с иммутабельностью тоже мимо. Парралелизм дает чистота функций и алгоритмы на map/fold/scan.
Что бы вы под этим не подразумевали :-\

То, что код на CPU и GPU процентов на 80 разделяем и удобно, когда он написан на одном языке, чтобы не вносить по 2 изменения.
Тот же Erlang прекрасно подходит для CUDA.

Динамически типизируемый функциональный язык. Подходит для CUDA. Здесь мне стоит остановиться, ведь я ничего кроме CUDA С++ не знаю, так что да, всего хорошего.
и что? у меня в проекте на ерланге тоже есть куски на це (драйверы устройств), но писать на цпп (а уж тем более на це) основную логику — извольте. возможно я конечно не крут в цпп, но мне кажется, что многопоточные приложения на нем писать чуток посложнее, чем на ерланге.
Не понял на счет «абсурднее требование». Автор сказал, что «С++ экономически не выгоден». Я указал ему на то, что есть сотни фирм, которые пишут именно на С++ разные продукты и получают прибыль. Значит С++ все-таки выгоден. Тяжело представить в реальном мире фирму, которая сознательно выберет убыточную модель развития.
То, что программа на каком-то языке хорошо продаётся, по-моему, лишь в небольшой части относится к тому, на каком языке она написана. Не тормозит и ладно. Язык скрыт от пользователя, да и торчал бы наружу — пользователю он редко бывает интересен. Фраза «С++ экономически не выгоден» означает, по-моему, что С++ редко бывает оптимальным выбором, на других языках идею программы можно было бы реализовать потратив меньше ресурсов при том же (а то и лучшем) качестве.
НЛО прилетело и опубликовало эту надпись здесь
А были бы они, если бы их надо было писать на сях?
НЛО прилетело и опубликовало эту надпись здесь
Ну основной отпечаток я, кажется, выделил: «Не тормозит и ладно.»
> Автор сказал, что «С++ экономически не выгоден». Я указал ему на то, что есть сотни фирм, которые пишут именно на С++ разные продукты и получают прибыль.

Нет, вы сказали следующее:
Мощный такой задвигон, как для языка на котором написано куча ОС, офисных пакетов, граф.редакторов, игр и прочей фигни, приносящей по пару сот лимонов производителю каждый год.


То, что огромное количество legacy-кода приносит прибыль не говорит об экономической выгоде С++. Новых крупных проектов на С++ достаточно мало и существуют они в достаточно узких нишах (embedded, HFT и т.п. и то там скорее С или С++ в стиле С с классами).

Там не скорее С с классами а именно С++. Например везде где я работал писали исключительно на С++, и везде где я ходил по собеседованиям (а таких фирм было много) был именно С++. И не только эмбедед. Да и вы про игры забываете.
Игры — да. Там нужна высокая производительность.
Она очень много где нужна. Кругом, когда заходит речь о реальном железе, видео, звуке, дровах, 3D, кешировании, поиске, работе с данными в террабайтных объемах и т.д. Просто люди, работающие в другой нише (в том же Вебе, например) от этого мира далеки и считают, что его нет. А он есть и он огромен.
— Не должно быть больше 4 вложенных конструкций. А если очень надо? — Разделяй на функции.

Ну, это нормально в любом языке программирования.

И вообще:
Вывод очевиден: мне erlang OTP помогает и судя по crtmpserver, я уже сэкономил около 3-х лет на отказе от C++
Я так и не понял: вы жалуетесь на язык или на практики, которые вас кто-то заставляет применять? Мне показалось второе. Не хотите писать get/set мусор, не пишите. Я делаю public и все ок (правда у меня Java, но если следовать всем «хорошим» рекомендациями тоже выйдет ужас). Ну и так далее. Здравый смысл всегда побеждает рекомендации, которые, кстати, созданы для новичков. А вы, как я вижу, уже созрели что бы думать своей головой на 100%. Так что вперед и с песней!

Еще как-то смутил этот ваш аргумент «юниор не поймет». Пусть учится! Понимание тонкостей языка — это такая мелка задача по сравнению с бизнес-задачами, что вообще не понятно зачем вы таких не обучаемых держите.
Тонкости в C++ и тонкости в Java — это разные уровни бытия. Кроме того в плюсах непонимание бывает деструктивно.
Похоже дело не в языке…
>И начинаю жалеть за бесценно проведенные годы за изучением стандарта С++, попытками написать свой фронт-энд компилер.

А зачем это было делать? Почему просто нормально не ползоваться языком для именно практических вещей и радуясь тому что с ним можно достичь почти гибкости скриптовых языков с темплейтами и перегрузкой операторов, и при этом выполнять код в 300 раз быстрее?

«загоны» с++ типа get const volatile — не каждый день c++ программера, а используются в отдельных конкретных случаях. Если кодер правильно всё делает, то именно в тех случаях когда это удобно. И даже если вы натыкаетесь на такой загон в чужом коде, то достаточно прогуглить его и за 5 минут всё станет понятно. Не нужно писать свой компилятор для этого… И не нужно про ВСЕ эти загоны знать и заучивать наизусть стандарты. Вы может ещё и каждый RFC как художественную литературу читаете?

Ну а если вы поддерживаете код которые писали обезьяны так не в языке дело, а в обезьянах. И чем гибче язык тем больше на нём способов написать фигню. Кому это не нравится могут программировать на Visual Basic.
> радуясь тому что с ним можно достичь почти гибкости скриптовых языков

Нельзя.

> и при этом выполнять код в 300 раз быстрее?

скорость ради скорости никому не нужна.

если нужен скриптовый язык, то:
— для того, чтобы достигнуть их скорости нужно убить неиллющорное кол-во времени на изучение C++, чтобы застваить шаблоны вести себя так, как надо
— разница в скорости редко критична
— если скорость критична, то критичный участок переписывается на С/С++ безо всяких шаблонов и продолжают использоваться другие языки
Когда скорость не нужна и не нужны нативные функции, так и используйте скрипты, кто мешает? Вроде никто и не говорил что для написания простеньких сайтов скажем С++ подходит также хорошо как perl или что-то типа того.

Что я имел ввиду это что С++ создаёт нативный код (который кроме всего прочего при небольших затратах ещё и портируется на все платформы и OC), И ПРИ ЭТОМ приближается к гибкости к скриптам, если правильно использовать нужные фичи.
> Вроде никто и не говорил что для написания простеньких сайтов скажем С++ подходит также хорошо как perl или что-то типа того

Кто-то говорил только про простенькие сайты? Ниша С++ вообще сйчас очень узкая. При условии прямых рук прежде, чем сайт на скриптах начнет тормозить, все упрется в базу данных или пропускную способность сети.

> Что я имел ввиду это что С++ создаёт нативный код

Его создает не только С++, но и, если не ошибаюсь, OCaml, который в итоге может давать код быстрее С++-ного.

> И ПРИ ЭТОМ приближается к гибкости к скриптам, если правильно использовать нужные фичи.

Повторю во второй раз, с добавлением:
— нет, не приближается
— для того, чтобы хоть как-то приблизиться, надо потратить ОГРОМНОЕ количество времени на изучение и понимание того, как работают шаблоны и прочая магия
— шаблоны могут не дать явного прироста в скорости работы и — главное — не дадут прироста в скорости разработки
> Кто-то говорил только про простенькие сайты? Ниша С++ вообще сйчас очень узкая.

Всего-лишь большинство десктоп-программ, высокоуровневых частей ОС и почти всех библиотек…

> для того, чтобы хоть как-то приблизиться, надо потратить ОГРОМНОЕ количество времени на изучение и понимание того, как работают шаблоны и прочая магия

Не огромное, а просто время. И ясное дело что за скорость+гибкость надо платить и за 5 минут никто не научится кодить как люди потратившие на это годы. Вы в этом пункте знаете какую-то альтернативу c++? которая лучше?

>шаблоны могут не дать явного прироста в скорости работы и — главное — не дадут прироста в скорости разработки

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

Насчёт прироста в скорости разработки — ну тут вы просто неправы. Если бы ими небыло удобнее пользоваться (то есть быстрее кодить), то их никто никогда бы не придумывал и не использовал. Да я и не только про шаблоны а вообще про фичи языка.
> Всего-лишь большинство десктоп-программ, высокоуровневых частей ОС и почти всех библиотек…

Вы тоже путаете legacy и новые проекты :-\

> И ясное дело что за скорость+гибкость надо платить и за 5 минут никто не научится кодить как люди потратившие на это годы. Вы в этом пункте знаете какую-то альтернативу c++? которая лучше?

В каком пункте? В пункте гибкости? Скорости изучения?

> Насчёт прироста в скорости разработки — ну тут вы просто неправы. Если бы ими небыло удобнее пользоваться (то есть быстрее кодить), то их никто никогда бы не придумывал и не использовал. Да я и не только про шаблоны а вообще про фичи языка.

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

в каком итоге и когда уже этот итог наконец наступит?
В итоге компиляции. И у нетеоретиков он наступает очень быстро.
Как раз наоборот. Этот итог наступает очень быстро только у теоретиков. На практике же " критические по скорости участки кода переписываем на С/С++". Давайте уже конкретные примеры, если действительно это наступает на практике, а не в умах теоретиков.
Вы, в общем, неправы. Скорости процессоров уже почти не растут, лишние ядра не позволяют ускорить однопоточные задачи, и даже производители браузеров (омг, программ для просмотра текстов!) стали меряться скоростью работы скриптов.
Сказать «Наша прога тормозит? купите новый компьютер» уже не получится. Таки придется учиться писать эффективный код на эффективных языках.
Вы делаете неправильные выводы из того, что я не писал.

Я писал ровно одно:
— разница в скорости редко критична
— если скорость критична, то критичный участок переписывается на С/С++ безо всяких шаблонов и продолжают использоваться другие языки

Тут нет ничего ни про тормоза ни про лишние ядра. Я сказал ровно то, что сказал.
> радуясь тому что с ним можно достичь почти гибкости скриптовых языков с темплейтами и перегрузкой операторов, и при этом выполнять код в 300 раз быстрее?

omg. на дворе 2011 год, люди давно научились неплохо jitовать различные скриптовые языки.

средний программист что на скриптовом языке, что на С++ нарисует код довольно близкий по производительности.
В копилку:
в конце объявления класса/структуры ставь; — или потом хрен найдешь где ошибка
std::list<std::list > — не забудь пробел!
itoa, atoi, _itoa, _atoi, _itoa_s, _i64toa, ui64toa, _ui64tow, _ultoa_s, WideCharToMultyByte(CP_UTF8, 0, str, len, 0, 0, 0, 0), null-terminated strings убейся
шаблонную функцию практически нельзя перенести в cpp
дружественные классы и операторы ввода/вывода, их перегрузка
и тд и тп
std::string<std::list >
Твою мать, хабрапарсер!
Теги <pre> или <source> — отличная магия против хабрапарсера.
…и кнопка «предпросмотр»
Про не забудь пробел пофикшено в С++0x.
А про всё остальное, включая null-terminated string — это ж С, при чём тут С++?
По поводу того, что идет после null-terminated strings, не очень понятно, в чём собственно претензия.
Признайтесь себе, что вы просто любите программирование.

Вряд ли вы несколько лет упорно учили стандарты, если бы вам это не нравилось.
Просто вы устали. Отдохните и получайте удовольствие дальше.
Меньше читайте теоретиков программирования, ну или хотя бы меньше им верьте. И будет вам счастье.
Си++ действительно перегрузили лишними абстракциями, но вы не обязаны всем этим пользоваться. С появлением auto язык вообще потихоньку превращается в почти человеческий, оставляя при при этом возможность писать быстрый код… Ну и вообще у вас проблемы не с Си++; в java, php и даже javascript ситуация часто та же самая.

Вам просто забили голову ерундой. Класс Бога, делегирование, абстрактные фабрики, обязательные тривиальные геттеры/сеттеры… Если от вас требуют эту ерунду на работе, меняйте работу.
Добавить геттер/сеттер атрибута в живой проект, если он вдруг понадобится — тривиальная задача, решаемая за пару минут. Пара запусков Find in files, а дальше компилятор подскажет те два с половиной случая, где надо подправить руками. Не надо их создавать на всякий случай, «чтобы были», вы не лабораторную в институте делаете.

Делегирование, фабрики-шмабрики тоже в мусорку. Самое главное — это правило третьего раза: никаких лишних абстракций (функций, классов, интерфейсов), до тех пор пока вы не скопипастите какой-то кусок кода в третий раз. Выполнять это правило нужно абсолютно строго. Даже если вы точно знаете, что третий копипаст вам нужно будет сделать через месяц — ни в коем случае не создавайте абстракцию сейчас. Вот через месяц и создадите, когда понадобится. Это правило вообще нужно писать большими красными буквами на каждой странице каждой книги по паттернам, прости Господи, проектирования.

Нормальная функция должна занимать 10-30 строк в идеале; ну хотя бы 5. Нет, ну бывают конечно функции для «синтаксического сахара», но речь не о них. Человеку банально удобно работать с функцией на одной странице, когда она вся перед глазами и не надо никуда прыгать. Странично-слайдовое мышление, семь объектов и всё такое. Никто не убьет котенка, если вы залезете в соседний класс и вызовете его функции напрямую, без делегирования и подъема десятка интерфейсов, если того требует логика вашей программы. И если класс чего-то вроде «документ» или «главное окно» имеет 300 или даже 500 членов — совершенно ничего плохого в этом нет, это действительно год-класс для вашего приложения, который так или иначе отвечает за всё.

Да, по сегодняшним меркам подобный код, если мягко, «немодный» и даже «попахивает говнокодом», но это всё понты и шелуха. Если её отбросить, то код получается очень простым и понятным, его банально в три раза меньше, и главное он пишется очень быстро. Программист должен решать задачи, а не создавать абстракции.
Последнее предложение хоть на печать и в рамочку, хорошо сказано :)
А я бы первые два. И в золотую рамочку :)
НЛО прилетело и опубликовало эту надпись здесь
несмотря на то, что программирую на С++ около 5 лет, до сих пор считаю, что не знаю его. Постоянно натыкаешься на какие-то подводные камни, которые найдешь только в стандарте, и то хрен поймешь без жесткой травы :) А вообще С++ напоминает мне какой-то просто супер охренительный гаджет, который может делать почти все, на котором куча кнопок, 5 килограммовый талмуд с описанием, и хрен пойми куда тыкнуть, чтобы просто заказать пиццу :)
А его никто не знает.
это как общая теория относительности: никто толком не знает, все про неё слышали, что она крутая штука, и находится куча критиков, которые утверждают, что это слишком сложно и поэтому неправильно
а ОТО разве в школе не изучают?
В школе вроде только СТО
Тоже спасибо, поржал. В школе толком классическую парадигму относительности Галлилея не понимают, о какой СТО может идти речь?
Ну у нас в школе было СТО, точно помню. А ОТО не было и в универе.
Да, в школе СТО точно преподаётся. Ясно понятно, в самом поверхностном и описательном виде, но всё же. ОТО в универе был, мельком, ну и в аспирантуре тоже было.
Спасибо, поржал.

Кафедра теоретической физики физфака ВГУ, магистратура. ОТО есть только в виде вводного спецкурса.
Там, простите, нелинейное дифференциальное уравнение в основе всего лежит, на тензор энергии-импульса. А вы говорите — в школе.
Ну извиняюсь, весьма давно учился.

Тем не менее, аналогию «на пальцах» с изогнутой резиновой плёнкой и геодезическими линиями помню со школьных времён.
Хотя метрический тензор не понимаю и сейчас.
Ну, для меня «изучать» — это не про популярное объяснение на пальцах и резиновых плёнках.

Кстати, искривление плёнки с грузом — именно иллюстрация, что такое метрический тензор ;). Кстати, о метрике речь идёт и в СТО — как раз оттуда она попала в ОТО и была «повышена» до ранга физического поля.
Ну да, я запросто мог попутать СТО и ОТО школьного уровня.
Математика это тоже язык, его никто не ограничивает искусственно, более того, он постоянно совершенствуется для нужд человечества путём ввода новых формализмов и т.п., но, тем не менее, многие задачи имеют запредельно сложные решения и многие — слишком избыточные. Это что, проблема языка?
С++ многое дал миру, как в форме средства разработки, так и в форме новых концепций. Никто до сих пор не знает, как должен выглядеть идеальный язык программирования, поэтому появляются языки, ориентированные на специфические задачи. Если в вашей задаче некий язык применять не удобно, то, быть может, не стоит этого делать?
Не нужно забивать гвозди головой — она предназначена не для этого.
Математика и С++ это антонимы.
"… Скучно стало в академ кругах, и ай да еще:
Тут тебе и rvalue-ссылки &&, и constexpr, и шаблоны с переменным количеством параметров. Без этого ж не кодилось.

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

В том же Мейерсе написано почему не желательны данные конструкции. Поэтому это вовсе не бред.
Ну давайте уберём goto. А потом обломимся и как в java добавим метки циклам. А потом всё равно ещё раз обломимся. Так как существуют алгоритмы, которые без goto решаются крайне не эффективно и запутано.
— Параметры макросов в скобках. А вообще макросы нельзя употреблять! Это же нарушает типизацию.
Зашибись! Да уже сейчас народ такую муть пишет — простая программа, а там тип на типе и типом погоняет и все друг-другу родственники. И две трети времени потом уходит уже на обслуживание этой иерархии типов. С какого перепугу сложные шаблоны стали более запутанными чем макросы?!
попытками написать свой фронт-энд компилер.
Вот с этого момент можно подробнее? Ну очень интересно.
Наверно автор хочет свойств, делегатов, ивентов и других «вкусняшек», которые видел в более высокоуровневых языках.
Так в C++ тоже это всё реализовано, но как только сталкиваешься с внутренним устройством, возникает желание, что лучше б это был синтаксический сахар.
? пежНаверно автор хочет свойств, делегатов, ивентов и других «вкусняшек», которые видел в более высокоуровневых языках.

Тогда автору нужно просто посмотреть на Qt :)
Там и свойства, и евенты, и сборщик мусора, и прочие вкусности.
Ну, что ты жалуешься? C++ в сто раз проще чем любой натуральный язык (русский например). И нормально, когда тебе нужно использовать один из семи падежей, выбрать окончание и еще помнить обо всех исключениях; все это дело происходит совершено без напряжения и автоматически. Конечно, иногда приходиться задумывать, какое же слово употребить «одеть» — «надеть». И при письме постоянно приходиться думать, где поставить запятую, а где не надо, нужен ли в этом слове мягкий знак или нет. Представляю нытье писателя-фантаста о том, что русский язык мешает полету его фантазии.

Я согласен, что C++ сложный язык по сравнению с другими языками программирования, но по сравнению с любым натуральным языком он очень простой. Я думаю достаточно двух недель, чтобы освоить C++ на довольно-таки хорошем уровне, чтобы можно было начать писать программы. Чтобы же начать говорить по-английски, я думаю, нужен год. И практика, практика, практика… все эти конст, мьютабл, геттеры/сеттеры со во временем будет вылетать на автомате, как жи/ши пиши с буквой и.
Когда я учился в школе, падежей было шесть. Неужто добавили ещё?
Вообще их больше. Например звательный падеж (вокатив): Миш, Гриш и т.п. Да, это отдельный падеж. Или вот «в лесу» и «о лесе». Второе — известный со школы предложный, первое — местный падеж (локатив, второй предложный). Подробнее тут
Спасибо за ссылку. Думал, что в русском нет «звательного падежа», как в украинском («кличний відмінок»). В русском почему-то всегда воспринимал подобные слова просто как некую сокращённую форму.
А это и есть форма.
Звательного падежа в русском давно нет.

Есть лишь осколки двух видов:
— исторически (Господи, Боже)
— в именах (Петь, Маш, Вань)
НЛО прилетело и опубликовало эту надпись здесь
и склонений как бы больше трёх. Например, есть класс существительных «на мя», которые не относятся к первому склонению — ибо склоняются по-другому, например, «пламя». «племя», «знамя» и прочие
НЛО прилетело и опубликовало эту надпись здесь
Их не так и много — сойдут за исключение из правила.
На школьном уровне — безусловно. В школьной программе много сознательных упрощений или даже устаревших теории от которых в действующей науке давно отказались. В задачи школы не входит быть на переднем краю.

Так вот с точки зрения науки, исключения — это повод задать вопрос «почему». Ответ на него есть — это отдельная категория логично ложащаяся в структуру языка. То, что в этой категории не так много слов — это вопрос лишь количества, по остальным критериям она ничуть не хуже тех, которые вошли в школьную программу.
Кстати, не считаю политику сознательных упрощений правильной. Вернее упрощать-то нужно, но нужно и сообщить, что это упрощение. Глядишь у детей бы больше интереса к предметам было.
Согласен.
А мне, глядя на ваш список, кажется, что эти понятия просто исконно русские (или праславянские)
НЛО прилетело и опубликовало эту надпись здесь
Хе-хе. Я вот больше склоняюсь к тому, что они как раз заимствованные.
Например, слово «имя» в польском языке звучит как «imię» [имен]. И падежные формы, так похожие на русские, образуются как раз вполне себе по польским правилам: imieniem, imiona etc.
НЛО прилетело и опубликовало эту надпись здесь
Тут не могу ничего сказать, я учил уже послереволюционную орфографию :)
«именно в польском языке как раз прослеживаются четкие правила, по которым можно понять, в каком русском слове писать «ѣ», а в каком «е». „
Не только в польском даже.
Просто и в русском эти буквы ранее различались, а потом стали звучать одинаково.
В школе и склонений было три, потомучто различия "-ом/-ём -ым/-им" русскому ребёнку и так интуитивно понятно.
А если раскладывать в формализм такого же уровня как c++, то склонений получится 9, с девиациями.

Задачка, чтобы проникнуться нецелочисленным количеством падежей:
Обычно «неодушевлённые» существительные в винительном падеже имеют форму именительного, а «одушевлённые» — винительного («он и микробы/микробов убивает»).
Но в женском роде во множественном числе можно говорить и так, и эдак («принести тарелки»/«принести тарелок»). Попробуйте объяснить (например, иностранцу) — в чём разница в употреблении этих форм?
Это относится не только к множественному числу (напр. «принести пива, стульев»). Родительный падеж употребляется тогда, когда подразумевается «некоторое неопределенное количество и при этом не слишком много».
И я должен обо всем этом помнить???? Ужасный язык.
Разумеется, нет. Стройте предложения исключительно на английском, исключительно вида «подлежащее сказуемое дополнение». И вас ждёт успех.
Еще говорят, что русский устаревает.
это именно к множественному относится, в единственном числе ни «некоторое», ни «конкретное» количество не получится.
а вот то, что не только к женскому — это да, я что-то подогнался.
но одушевлённость имеет больший приоритет, с одушевлёнными такой фокус не пройдёт.

но мне вот кажется, что дело не в количестве, а в определённости.
«найти пиво», «принести терелки» — это «the beer» и «the dishes», а «найти пива», «принести тарелок» — это «some beer» и «some dishes» ('some' в роли неопределённого артикля множественного числа, которого не бывает).

при этом происходит reinterpret_cast из штучных вещей (три стула) в неисчислимые (ведро стульев).

и, однако, при указании конкретного количества используется родительный падеж,
за исключением [1234] и чисел, оканчивающихся на [1234] (кроме 11-14), для которых наоборот — именительный.
(тоже весьма весёлое «правило» само по себе,
хорошо ещё, что не надо каждые 400 штук обратно в родительный переигрывать)
Да, я имел в виду, что не только для женского рода. Ночь была, мысли уже путались) Впрочем, для неисчислимых существительных (см. пиво) работает и в единственном числе.
Одушевленность де-факто роли не играет, просто потому что для одушевленных существительных родительный падеж совпадает с винительным. Тем не менее, иногда форму родительного падежа можно специально сымитировать: «Эй, накопай человеков на ужин» — родительный падеж с винительным для «человеков» тоже совпадают, но в данном случае родительный падеж «человеков» противопоставляется винительному падежу «людей».

Количество тоже имеет значение. Когда употребляется такая конструкция, никогда не подразумевается большого количества субъекта. «Принеси петрушки» — это всегда будет означать «чуть-чуть, один раз приготовить», а «принеси битума» — это максимум ведёрко, щель замазать, но никак не столько, чтобы покрыть всю крышу.
Во-первых, в случае с exception — зачем вам все эти getReason(), конечному пользователю они вряд ли интересны. Во-вторых, вас никто не заставлял использовать десятиэтажные конструкции на STL-шаблонах, верно? В реальности нужны всякие структуры, map, vector, и пожалуй, все. Пишите проще, и все будет работать нормально.

Ну и смешно читать комметарии тех, кто предлагает возвращаться на Си. И будет каша, как в Друпале, из тысяч никак не связанных функций, структур и глобальных переменных. А еще пляски с определением, кто должен выделять место под строку, вызывающий функцию или сама функция, а еще ручная проверка длин строк (чтоб буфер не переполнился) и постоянное использование костылей типа strdup() — которые по хорошему, надо бы каленым железом выжигать из недопрограммистов.

А еще в Си не работает перегрузка функций.

Да вы посомтрите на реализации банальной хеш-таблицы, там 20 функций типа map_add_int(const struct MapInfo * map, char * key, int value) — ну это же треш и ужас. И map->add(...) в 100 раз проще и логичнее написать. А еще использование допотопного char* вместо настоящих строк с разделяемым буфером.
А еще пляски с определением, кто должен выделять место под строку, вызывающий функцию или сама функция, а еще ручная проверка длин строк (чтоб буфер не переполнился) и постоянное использование костылей типа strdup() — которые по хорошему, надо бы каленым железом выжигать из недопрограммистов.


А мой начальник говорит, что такой код надежнее всяких там «новомодных» конструкторов/деструкторов и прочих «излишеств» вроде STL и прочих RAII. :)
Меняйте работу.
Я вам больше скажу: С++ — жалкое подобие английского языка! Вот уж где переизбыток всяких сложностей. Одних времен сколько — запутаться проще, чем в шаблонах STL. На каждое слово — по исключению. Неправильные формы глаголов! Как правильно произносить слово live — «лайв» или «лив»?!

Ужас, правда?

А то вот еще, бывает, смотришь на девушку красивую, думаешь — может, подойти, познакомиться? А опыт богатый, зараза такая, подсказывает: да проблемы же сплошные от девушек этих! Лучше уж одному жить, зато спокойнее, да и с экономической точки зрения выгодней гораздо…

Когда пишешь на каком-нибудь другом языке и неожиданно упираешься в ограничение, которое в С++ ты бы обошел с легкостью (а то и вовсе такого ограничения не встретил) — вот это настоящее «достало» получается.
Кстати, в английском три времени глагола, как и в русском. Просто ещё для каждого есть так называемые аспекты. Сорри за занудство.
Ну к слову говоря, их таки два а не три, что в английском, что в русском глаголы не имеют формы будущего времени ни там ни там.
Уберите лингвистов с Хабра! )) Вот так загоняете меня уже второй раз.

Ладно, у меня тогда вопрос касательно русского: «сделает» — глагол в форме какого времени?
будущее время, аспект: перфектив. В перфективе глаголы в русском не имеют формы настоящего времени, так что их (форм) по прежнему две. Надо было мне сразу уточнить.
Ну, если попытаться это закодить, то в сумме для глаголов всё равно получим какой-нибудь enum { Past, Present, Future };, так что всё-таки три формы.
Тут скорее будет множественное статическое наследование (template policies, ага), потому что грамматических категорий, помимо времени и аспекта еще очень много, и некоторые комбинации запрещены. К сожалению (а может и к счастью, потому что иначе все это не было бы так интересно) естественный язык не очень следует логике. Если это не Ithkuil конечно или какой-нибудь Lojban, но на то они и conlang'и.
Всё, я сдаюсь :)
'быть', 'делать', 'иметь', 'идти' — самые неправильные глаголы, наверное, во всех языках мира.
НЛО прилетело и опубликовало эту надпись здесь
А вот это было бы интересно —
часто ли встречаются такие ограничения в других языках, котрые в c++ легко обходятся?

Ну сколько можно? Начинаем неделю ненависти к C++ (дубль N)?
> А в голове крутится: надо чтоб не было класса Бога, поэтому делегируем обязательства, надо передавать объект по костантной ссылке, метод тоже должен быть const, а вдруг нам нужно будет изменять что-то… ммм… тогда объявлю m_detector как mutable. Но тогда моего коллегу джуниора может это смутить… что-же делать.

У опытного С++ программиста подобные вопросы решаются в фоновом потоке мышления, почти на автомате.

> Зачем? Вот спрашиваю себя, зачем я теперь все это знаю.

А зачем вообще программировать? Вам нравилось это учить, поэтому теперь и знаете. Вам что, мозга жалко что-ли? Все равно все на свете не выучите. К тому же С++ программисты востребованы и хорошо оплачиваются, так что явно лишними эти знания не будут.
Программисты на С++ знают лишь 20% языка, но проблема в том что разные программисты знают разные 20%...(с) кто-то там…
По моему это адаптация 80/20 Паретто, Тогда надо расширить
80% программистов С++ знают 20% языка
20% программистов С++ знают 80% языка.
Т.е. на 100% с++ не знает никто, теорема доказана :)).
В своё время открывал александреску и элджера только чтобы поржать.

Думал что этот мир сошёл с ума, раз люди пишут на этом и пишут это. Очень рад что многие разделяют отношение к с++ как к абсурду.

Тогда с++ не любил не со стороны питона и си шарпа, а со стороны простого Си. Да, и в своё время был профессиональным с++ программистом.
Ну наверное не «был», а «считал себя» профессиональным С++ программистом — это разные вещи, поясняю на всякий случай — вдруг вы «были» ещё и «профессиональным логиком».
Программировал на с++ и получал за это деньги. Вроде так определяется профессия.
Профессия, а не профессионализм.
Формальго-да. Фактически профессионализм, в смысле глубоко знания, слабо кореллирует с зарплатой.
Куда уж мне до вас, великий гуру.
Эй, погодите, Гуру — это я ;)
Интересно в ответ услышать мнение человек, который писал на c++, но не использовал всего этого, а писал как придется. Кто лучше и дальше продвинулся и преуспел — вот и будет показатель, что же зло и добро.
А к самому языку непосредственно это не относиться.
Ну, скажем, без boost из-за переусложнённости последнего пишут многие. Во многих случаях из stl используют только коллекции и алгоритмы (не используя потоки).
Спасибо за статью, прямо таки улыбался, когда читал!!!
Теперь по делу. Ну, если бы С++ был такой же как и С, то это было бы странно :). Вы же не забывайте, что многие приёмы в C++ были созданы чтобы максимально обогатить парадигму объектно-ориентированного программирования. И многие из них большинству не нужны, но должны быть для настоящего ООП языка. Но перегибать палку на местах естественно не нужно. Я сам когда-то на занятиях по численным методам в Вузе извращался и делал такое, что вспоминать страшно, хотя даже различные методы решения уравнений реализовывать в отдельных функциях не было надобности — я это никогда не использовал.
Так что правильнее не ругать язык, а тех, кто необоснованно требует лишнего.
Высказывая утверждения, что C++ слишком сложен, Вы пропагандируете подход, оринтированный на аутсайдеров.
Дескать, зачем использовать в разработке сложные языки/технологии, если мой штат программистов, сплошь состоящий из джуниоров-пхпшников, это не осилит?

Далее. Ваши слова:
> Вот, например, из зазубренных постулатов: объекты в методы передавать как константные ссылки.
> Это простой пример, где решение задачи напрочь смывается из памяти этими всеми «плохой тон программирования».
«Зазубривание постулатов» — это проблема; проблема, вызванная непониманием основополагающих принципов языков C (sic!) и C++. Я хочу сказать, что осознание основ языка освобождает от необходимости что-либо зазубривать — и это справедливо не только в отношении программирования.

Насчёт бреда:
— Никаких goto
На этот счет единого мнения не существует, стоит только немного поискать — найдёте разнообразнейшие холивары, суть которых сводится к тому же: «использовать goto — недопустимо, т.к. любой джуниор-пхпшник с его помощью может люто набыдлокодить».
О том, что проблемой в данном случае является не оператор языка, а сам быдлокодер, речи почему-то не заходит. Но я, однако, отвлёкся.
— Параметры макросов в скобках.
Не осилил. Виноват.
— А вообще макросы нельзя употреблять! Это же нарушает типизацию.
— Никаких указателей, даже если очень хочеться. Только умные, с 4-мя шаблонными параметрами.
— Никаких глобальных переменных. Низя!
См. пункт о goto и джуниорах.

— reinterpret_cast, static_cast, const_cast. Почему нет private_to_public_in_case_exception_cast?
Цитирую Википедию: «Громоздкие ключевые слова являются напоминанием программисту, что приведение типа чревато проблемами.».
Не нравится — используйте function-style cast, или C-cast.

Дальше рассматривать Ваши доводы поленился, да и суть моих возражений радикально не изменится.
Резюмируя:
C++ — это мощный и сложный инструмент; если он Вам представляется необъятным — никто не принуждает к его использованию.
И, да, я не являюсь большим фанатом C/C++, честно; я предпочитаю подход, основанный на очевидном здравом смысле — «инструмент подбирается сообразно решаемой задаче». В качестве факультатива, попробуйте подобрать актуальную замену C++ для такого проекта, как, скажем, Firefox (пример первым пришел в голову).

С уважением к автору.
P.S. Ничего личного, честное слово, просто взгляд со стороны: нелегко воспринимать всерьез текст, содержащий нехитрые ошибки правописания.
> Забываю про задачу как таковую. А в голове крутится: надо чтоб не было класса Бога,
> поэтому делегируем обязательства, надо передавать объект по костантной ссылке,
> метод тоже должен быть const, а вдруг нам нужно будет изменять что-то… ммм… тогда
> объявлю m_detector как mutable.
мне кажется вы здесь не правильно пользуетесь понятиями const и mutable и таким образом конечно все начинает рушиться. Когда параметр передается как const он обещает не менять состояние объекта, если он что-то меняет не нужно ставить const. Mutable это для исключений, когда что-то не описывает состояние объекта.

> С членами классов работать через set/get методы. Даже если у вас класс Exception с
> одним членом reason, нам нужно, по правилам хорошего тона, объявить конструктор,
> метод Get, метод Get const, можно и Get const volatile, а вдруг пригодиться? А как
> насчет пойти дальше, сделать все методы приватными и добавлять по friend'у, кто их
> использует? Ах да, не забудь про виртуальный деструктор!
Здесь просто подход в корне не правильный, если что-то ен нужно — не надо это писать. Каждая строчка кода потребует поддержки. Если вам не нужен const get не пишите его, я уже не говорю про volatile. Если вы не уничтожаете объект используя указатель на его родителей — не делайте virtual destructor.
Что впринципе верно и для других зачем в вашем посте — если вам это не нужно, зачем вам это использовать? Все правила и конструкции это разрешение каких-то проблем в неоднозначности и придает логическую законченность.
НЛО прилетело и опубликовало эту надпись здесь
Автор сделал своё дело.
Автор может уходить.
Пишите на Qt
Вот почему я люблю Ruby и Python
Ну, почему же?
НЛО прилетело и опубликовало эту надпись здесь
Все не так глубоко :)
В питоне я могу не парясь особо написать сложную логику, а компоненту требующую особую производительность вынести в С-шную библиотеку.
не многие языки обладают свойством «не парясь особо»,
об отсутствии которого в c++ топикстартер и говорит.
Т.е. я не могу написать библиотеку на С и использовать её из С++? ORLY
выражение «не парясь особо» относится к «написать сложную логику».
Вы писали сложную логику в C#? У Вас не получилось? Что такое сложная логика?
Не обращай на него внимания. Он тупой тролль, не знающий, что такое языки низкого уровня, высокого.
> В питоне я могу не парясь особо написать сложную логику, а компоненту требующую особую производительность вынести в С-шную библиотеку.
Неужели.
кстати, а они чем-то фундаментально отличаются?
(я знаю питон, а о руби только слышал)
Обильным «сахаром» в руби :)
этот сахар слащще декораторов?
а слащще лисп-макросов?
О, кстати, было бы интересно увидеть решение этой задачи на Руби:

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

На питоне уложились в 76 символов (не считая импортов):
stdout.writelines(sorted(_ for _ in open('test.txt') if _.count(' ')>2))
вобще, это 73 символа, а если убрать пробел перед if, то вобще 72 )
Рубисты, ау! Очень хочется рубинового сахарку попробовать :)
Пофиг, если не получится короче, главное чтобы сладким был.
Я не рубист (а только учусь), но вот так можно
IO.foreach('test.txt').select{|s|s.count(' ')>2}.sort.each{|s|print s}
и без всяких импортов :)

Не нашёл метод, аналогичный stdout.writelines у вас, потому .each{|s|print s} могло быть короче, наверное, но как бонус нужные строки возвращает в виде массива, можно ещё что-нибудь сделать )
Кстати, нашёл бы такой метод, пускай IO.printlines то соответствие задачи было бы почти дословное:
Вывести на экран — IO.printlines
все строки текстового файла — IO.foreach('test.txt')
в которых более трех слов select{|s|s.count(' ')>2}
отсортированные по алфавиту sort
Я не хаскелист (я только лечусь), но вот набросал что-то похожее на правду (вообще это кагбэ в одну строчку, но здесь не вместилось). Чисто для примера:

main = readFile "in.txt" >>=
       putStrLn . unlines . sort . filter ((3<) . length . words) . lines


Вроде работает.
Да, забыл. Импорты нужны

import Data.Char
import Data.List
Класс!
Ну, например:

puts [*File.open(«1.txt»)].grep(/(\w+\W+){3}\w/).sort

54
Фух, дождался возможности исправиться.

puts File.new(«test.txt»).grep(/(.+\b){7}/).sort

48
Эх, а ведь видел puts, но не посмотрел что она делает, думал как в Си )
Как-то так:
puts File.readlines("test.txt").reject {|i| i.count(' ') < 3}.sort

Избыточность влечет возможность выбора, а точнее необходимость оного. Из-за того что джуниоры выбор правильный делать не умеют родятся тонны говнокода. Тем не менее 70-80% Ваших тезисов отпадут если следовать принципам SOLID и придерживаться CodeStyle какого-нибудь показательного сообщества (например, Qt и вот ещё)
Очевидно, что любой инструмент требует подготовки и привыкания.
Чем инструмент сложнее, тем более серьёзная, более системная подготовка требуется.
С++ — мощный и сложный инструмент.
Для его применения требуется системная подготовка, дисциплина и привыкание.
К сожалению, мест, где на адекватном уровне дают системную подготовку к С++, у нас в современной России почти нет. Соответственно, никто не готовит будущего программиста С++ к дисциплине и не устраивает полноценный «инкубационный период» для привыкания.

С моей точки зрения, статья наглядно показывает недостатки отсутствия системного подхода, когда ряд подходов и практик создаёт мешанину в голове программиста. На которую он и реагирует вполне обоснованно.
Хождение на костылях тоже требует привыкания. Троллю так, помаленьку). Не считаете ли Вы, что автор туп как пробка, а вот у Вас-то с пониманием всё на 5?:)
Скажите, каким боком то что написали вы, относится к тому, что написал я?
Для тупых. Не старайтесь выглядеть умнее чем Вы есть. Вы, окончив свои 4 курса не умнее других. Спасибо, пожалуйста.
Друг мой, о каком курсе идёт речь? Мне уже четвёртый десяток идёт.
И давайте без «давайте» и переходов на личности впредь. Также рекомендую быть осторожнее с фразами, начинающимися со слов «для тупых».

Желаю удачи! Искренне ваш, mt_.
Вы так рекомендуете, будто у вас связи) Не буду использовать термин «для тупых», ограничусь термином «для Вас»! Не важно сколько Вам лет, рассуждаете Вы на на уровне. Я тоже могу померяться с Вами и не переживайте, эго у меня будет короче Вашего при любых раскаладах, я сразу предупредил, что троллю, я Вас прошу, перечитайте свой комментарий и подумайте. Вы так и пышете снобизмом. Автор не глуп, это правда. Вы тоже, я верю в это!
Автор — классический троль. Сидит, наверное, читает сейчас комментарии и хитро так улыбается.
Ты бы прикрылся, кроме как «тролль», «баян» и так далее… что-то бы сам запостил.
Из-за таких людей не хочется писать дальше.
Я вообще из песочницы и не собирался вызывать такой резонанс, постя, между половыми актами с индусским кодом.
Холи вар, холи вар, кого хочешь убиварй.
НЛО прилетело и опубликовало эту надпись здесь
Автор, ну прочитай ты Джефа Элджера, да Андрея Александреску. Зачем тут плакаться, не нравится С++ с его шаблонами, идите на Java или .NET. Там только обобщения, больше из них не выжать.

А если на то пошло, то шаблоны в С++ дают частичную мощь RTTI, без использования оного, что очень хорошо сказывается на производительности. Очень неслабые возможности метапрограммирования и т.д.
НЛО прилетело и опубликовало эту надпись здесь
«частичную мощь RTTI, без использования оного» — текст был таким, я лично RTTI не использую, но некоторую гибкость можно получить не используя RTTI. Я к примеру активно использую списки типов, свойства типов, специализации шаблонов, compile-time условия и т.д.

Какими большими возможностями обладает C#? Приведите пример.
НЛО прилетело и опубликовало эту надпись здесь
По сути метапрограммирование делится на 2 категории:
* времени компиляции — этим и славится С++
* времени выполнения — времени исполнения, ваши варианты

Да, в связи с отсутствием родной полноценной поддержки рефлексии, в С++ о метапрограммировании времени выполнения можно даже не говорить. А с другой стороны у C# туго с метапрограммированием времени компиляции. У каждого своя сильная сторона.
НЛО прилетело и опубликовало эту надпись здесь
А зачем мне генерация кода в рантайме? Если мне понадобится скриптовый язык, да это будет не просто, но я его добавлю и все. И если язык C++ является компилируемым, то зачем мне им генерировать код? Я никогда слепо не защищал какие-либо вещи и если есть инструмент лучше подходящий для определенной задачи, то я воспользуюсь им, а генерить код в рантайме на С++ я не собираюсь.

.NET я не обижаю, опыта мало, но .NET мне нравится, просто специфика компаний, в которой довелось поработать не позволяет в полной мере использовать .NET
НЛО прилетело и опубликовало эту надпись здесь
Я знаком с этими возможностями .NET и это одна из особенностей, за что мне нравится .NET, но увы данный функционал в зависимости от специфики может вообще не быть востребованным.
> Да, я пока пишу… Забываю про задачу как таковую.
А не проще было бы сначала продумать интерфейс, а потом программировать? Почему же незнание/неиспользование методологий разработки сваливаете на язык программирования.

> Так, члены должны объявляться с префиксом 'm_', чтобы не было.
Вас кто-то заставляет с плеткой это делать? Это не стандарт, язык этого не требует, я лично префиксы не использую, для подсказок есть IntelliSence, да и VisualAssist.

> С членами классов работать через set/get методы.
И что в этом такого, во многих языках нет свойств. А если уж хочется, то реализуются они не очень сложно, сам юзал, но вернулся на к set/get методам.

> Никаких goto. Лучше do { break; } while(0); От этого суть глобально меняется.
Я бы поспорил, goto нифига визуально не хороша, а break/continue проще отследить визуально. Я сам против goto, сколько программирую, всегда обходился без него.

> Параметры макросов в скобках. А вообще макросы нельзя употреблять! Это же нарушает типизацию.
Ну не хотите, не используйте, временами макросы дают некоторое удобство.

> Никаких указателей, даже если очень хочеться. Только умные, с 4-мя шаблонными параметрами.
Опять же вам решать, если работать с памятью нормально не умеете, живите с умными указателями. Я использую все, опять же в зависимости от места применения и не страдаю от этого.

> Никаких глобальных переменных. Низя!
А зачем? На кой это надо? Если сильно хочется есть Singleton. Да и найдите в других языках высокого уровня глобальные переменные.

> Не должно быть больше 4 вложенных конструкций. А если очень надо? — Разделяй на функции. Причем >протитип в хэдер, реализацию рядом с основной функцией.
Ну перейдите на другой язык программирования, используйте больше и запутайтесь сами в своем коде.

> Множественное наследование — плохо. Зато виртуальное наследование, спецификаторы
> доступа при наследовании, и какие они будут в наследуемом классе — надобно знать. Очень нужная?
> вещь… на собеседованиях
И вас кто-то заставляет это слушать? Отстаивайте свою точку зрения. Я использую множественное наследование и мой код от этого хуже не становится.

> reinterpret_cast, static_cast, const_cast. Почему нет private_to_public_in_case_exception_cast?
Вы еще забыли dynamic_cast ) Вообще на мой взгляд кастовать типы не очень хорошо, за const_cast сам оторву программерам руки, максимум, что позволю, так это mutable.
А вот временами без static_cast и dynamic_cast не обойтись. Хотя стараюсь проектировать, чтобы вообще не использовать виртуальность, приведение типов.

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

> А как вам такой пул потоков. Это при том, что задать нотификатор о завершении потока
И чем он плох, можно стратегиями задать поведение, что в этом плохого? Да и в чем сложность с нотификацией завершения потока? Вам не подходят условные переменные? А с другой стороны зачем поток должен кого-то уведомлять? Если уведомлять, то значит кто-то должен ждать, для этого нужен еще 1 поток, либо должен следить какой-то к примеру из основных, это нарушение концепций многопоточности. Так что уж решите, что вам надо.

И уж если вам многие возможности не пригодились, так не говорите это же про других. Ну не нравятся вам rvalue, не используйте новый стандарт. Не нравятся шаблоны, а тем более новые variadic, не используйте. Вообще судя по статье вам отлично подойдет BASIC.
вобщем-то согласен с вами, только вот добавлю:
> > С членами классов работать через set/get методы.
> И что в этом такого, во многих языках нет свойств. А если уж хочется, то реализуются они не очень сложно, сам юзал, но вернулся на к set/get методам

а в других ОО языках разве не надо использовать сеттеры-геттеры? утомляет писать руками — есть библиотеки. ах да, тут ведь еще макросы отлично подходят, но это рассово неверный подход. вобще их даже гуглы не стесняются пользовать (взгляните в pcrecpp.h)

> > Так, члены должны объявляться с префиксом 'm_', чтобы не было.
> Вас кто-то заставляет с плеткой это делать? Это не стандарт, язык этого не требует, я лично префиксы не использую, для подсказок есть IntelliSence, да и VisualAssist.

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

> > Никаких goto. Лучше do { break; } while(0); От этого суть глобально меняется.
> Я бы поспорил, goto нифига визуально не хороша, а break/continue проще отследить визуально. Я сам против goto, сколько программирую, всегда обходился без него.
в одном из недавних топиков в комментах обсуждали случаи, где это уместно (http://habrahabr.ru/blogs/code_review/125120/).

>> Не должно быть больше 4 вложенных конструкций.
это рекомендация кросс-языковая, с++ тут ни при чем.

> reinterpret_cast, static_cast, const_cast. Почему нет private_to_public_in_case_exception_cast?
быть может потому что он не нужен? все касты, имхо, архитектурно обоснованы — делают проверку типов в необходимой манере. const_cast — то, что все так ругают, сделан больше для того, чтобы дать выход программистам, если архитектурно не сложилось у них…

Резюмируя, могу сказать, что автор просто поддался модному тренду — поливать грязью язык.
> Например, хочешь использовать списки? Будь добр, пойми, что такое шаблоны, область видимости
я бы сказал: «если хочешь программировать, то пойми ...»
НЛО прилетело и опубликовало эту надпись здесь
отличное мнение!
Ув. nrcpp Вы что действительно думаете, что делаете что-то сверхестественное и уникальное?! Присмотритесь к жизни по-лучше.

С чего такой вывод?
Если вы заметили, то описать слабые места языка, в нашем случае избыточные — было целью топика. Не «язык N — говно.»
Похоже что автор занимается не тем, к чему у него лежит душа.
С++ это мощнейший инструмент, а вы похожи на обиженного ребёнка который пересел с детского велосипеда на папину машину и не знает как её завести.
Мне вас искренне жаль…
Грустно видеть, что всё меньше остаётся настоящих инженеров, сплошные (хал)«явщики»
Ну ну ну, кодю 5 лет исключительно на плюсах. НО:
— Как правило приходиться рефакторить С++ код, либо переписывать с нуля. Думаю, понятно почему создавать с нуля на плюсах — нынче затратно. (Обобщаем)
=> Рефакторю — ужасаюсь, переписываю с нуля — опять же, оглядываюсь на функционал индусского кода. Во истину, радость, когда и функционал и код мне подвластны. А так мы как раз получаем, пересел с индийского велосипеда на свою машину, а педали все равно крутить приходиться. При этом не забываем про «ПДД», читай хороший тон
Создавать с нуля всегда проще, особенно с оглядкой на предыдущий код.
А вот рефакторить всегда нелегко. Рефакторить плохо написанный код ещё труднее.
Для того каждый хороший программист и вырабатывает у себя с годами свой стиль кодирования.
Хороший и всеми соблюдаемый style guide в команде сильно упрощает чтение кода написанного коллегами. И это относится к любому языку программирования.

С++ не скрывает что там творится под капотом, можно всё подкрутить так как нужно и разобраться почему что-то там не работало. Вот этим он и удобнее.

Можно и на С++ написать что-то запутанное и непонятное, но это скорее претензии к тому кто это написал, а не к языку. Впрочем это ещё раз подтверждает широту охвата решаемых с его помощью задач.

Работу получается хорошо делать и получать удовольствие от неё когда её любишь. Может у вас просто усталость накопилась?
> С++ не скрывает что там творится под капотом, можно всё подкрутить так как нужно и разобраться почему что-то там не работало. Вот этим он и удобнее.

Ни один язык не скрывает. Инструмент, с которым работаешь, надо знать. И в любом языке можно «подкрутить под капотом, чтобы работало, как надо» :-\
Ну, вообще-то нужно знать несколько инструментов, и хотя бы два-три из них — очень хорошо. Из них и выбирать грамотно тот что лучше в данном случае.

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

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

Разумеется, если просто нужно съездить в булочную, то проще это сделать на велосипеде, а не на навороченном вертолёте с кучей кнопочек и тумблеров и контролем высоты.
Ну ну, самый страшный код, что я видел, рожали пхпшники и джаваскриптеры!

Я не знаю, может вам и затратно новый код создавать на плюсах, за других не говорите.
А на Бэйсике код совершенный пишут? А на Паскале?
Такой код мне в руки просто не попадался почти. Ну паскаль только давно, ну и дельфисты отжигают местами напалмом.
На дельфи писал давно и это было не правда, но там, по-моему (как и в VB), среда провоцирует на то, чтобы не отделять данные от представления, про логику вообще молчу. В PHP, впрочем, тоже провоцирует сам язык (изначально скрипт на PHP это чистой воды представление, в режим интерпретации языка специально входить надо). Но, имхо, это лишь говорит о свободе выбора. В PHP, если не брать чисто системную функциональность, свободы даже больше. Больше возможностей писать как говно-, так и совершенный код. Разве что свобода ось не убьёт.
Затратно, с экономической точки зрения. А более конкретно, С++ на практике — это рефакторинг и костыли, для уже написанного. Новый софт на плюсах с нуля? Для малого, среднего бизнеса, предприятия, стартапа? Пример пожалуйста.
Ну я как раз этим занимаюсь, внезапно. И пишу не в стиле говноподелок на MFC.
Судя по количеству плюсов, которые собрал пост, на Хабре либо одни хакеры и эмбеддеры (которые ничего, кроме pure C и ASM не признают), либо засилье PHP-шников и делфистов, либо все те, кто сам пишет на C++, тихо его ненавидят =).

Несколько раз пытался осилить ВСЕ фишки-премудрости C++, ни разу не выходило, так до сих пор на чистом C и пишу. Теперь после этой статьи посыпать голову пеплом не буду, спасибо автору и плюс в карму.
А почему «либо — либо — либо»? Почему не «и — и -и»? :)
Зачем осиливать все стороны С++? Это универсальный мультипарадигменный язык! Насчет засилия хакеров и эмбеддеров: я лично такого не наблюдаю, поэтому боюсь, что тут одни пхпшники да шарписты тусуют. Дельфистов же вымирают) И если вторых я еще могу понять, то первые просто не осилили и вряд ли осилят более серьезные ЯП. С третьими все вообще грустно.
Прямо как серпом… Я перешёл на PHP именно с С++ (три года разработки под MFC) после первой же попытки создать сайт на С++. Выбирал между Perl и PHP, подкупил очень близкий к C/C++ синтаксис во втором. Первое время очень не хватало ООП в PHP, потом не хватало нормального ООП, сейчас не хватает в основном сахару типа перегрузки функций в С++ или именованных аргументов в Python. Так же первое время бесила невозможность написать что-то вроде getSomeArray()[0] или (new SomeClass())->someMethod(), но привык заводить временные переменные в первом случае, а во втором использовать методы класса или также заводить временные переменные. Не хватает контроля типов атомарных параметров, но спасает phpdoc.

В общем PHP не идеален, но методы обхода его недостатков наработаны годами. И как-то грустно слышать, что самый популярный язык в вебе использую лишь потому, что не осилил более серьезный язык, хотя осилил и асм, и С++, и FORTH, но вот на PHP для веба писать почему-то быстрее, а главное — не смотря на его «несерьезность» (А в чём она заключается? Через задницу, но почти всё можно сделать) он остаётся самым востребованным на рынке у заказчиков. Как я понимаю, не в последнюю очередь благодаря легкости деплоя и администрирования LAMP. Будет заказчиков на Ruby или Python столько же — с удовольствием перейду на них, но где они?
С++ и разработка на MFC как-то не вяжутся, MFC вообще не С++! Это «Си с классами»!
Зачем осиливать все стороны С++? Это универсальный мультипарадигменный язык!

:) Ну и в то время С++98 был только принят и Visual C++ 6.0 его полностью не реализовывал, STL, например, «изкоробки» не было.
И получился уродский монстр, по которому некоторые потом судят о С++ до сих пор!
По-моему, самая массовая реализация C++ на то время. Да и на это тоже, вроде бы.
PHP вообще очень узкоспециализированный и нишевый ЯП.
И это делает его «несерьезным»?
Все в сравнении познается, я на PHP много кодил и не скажу, что был в восторге от языка, а уж от фреймворков с ООП головного мозга и подавно.
Ну несерьезный язык для меня Лого, например. А вот когда я начал писать на С++ под веб, а затем открыл для себя PHP, то был от него почти в восторге (классов не хватало и некоторые несуразности типа невозможности написать func()[0] или (new Class())->method(), первое обещают в следующем релизе, второе пока нет :(). Но несмотря на это, код на PHP получался более лакончиным, одно то, что не нужно было ручками разбирать CGI Environment, а можно было просто воспользоваться $_GET, $_POST, $_SERVER и $_FILES (вернее тогда они назывались по другому и светились напрямую в глобальном нэймспэйсе) делало код куда более лаконичным.
+1, на кнопку кармы не хватает =)
Ну вот, я потратил все минусы на Ваш пост, Вашу карму и комментарии.
Все попытки нововведений в С++ не делают код более понятным, поддерживаемым и быстро компилируемым. Более того, предлагаемые стандарты, явно свидетельствуют о том, что программирование на С++ опасно для психики.
Истеричка… :) Все что попадает в стандарт С++ выстрадано и написано кровью. То, что кажется неудобным вам лично, поможет тем, кто будет читать ваши исходники в будущем, оградит ваш и чужой код он неправильного использования и идиотских ошибок не только на стадии выполнения но еще на стадии сборки. А если в этом нет необходимости — пишите на C# или вообще PHP. И к слову, много ваших примеров это не только С++, сколько конкретные реализации. Скажем так, я вообще не понимаю как можно писать вменяемый код на STL, однако это сугубо мое мнение. Хотите писать красиво и понятно — пишите.

Публикации