LINUX.ORG.RU

10 причин почему программист на С++ может выбить много денег


24

10

Список в конце поста написан Лавсаном 2 года назад. (2011-03-23 19:56:00) (источник)
Надеюсь, автор не подаст жалобу в Роспатент за перепечатку :-)
Кстати, sudo cast lovesan.

Чтобы проверить актуальность вопроса, всю последнюю неделю я долго и нудно использовал этот список в дискуссиях. Чтобы разобрать отдельные пункты отдельно.

Временное резюме: С++ всё еще актуален по историческим причинам. Еще есть мобилки (sudo cast mono), гиперкластеры для шиндовс 3.11 (sudo cast vromanov) и базы данных. Т.к. он актуален, но не предназначен ни для чего (см. выводы в конце списка) новых специалистов по нему должно быть мало. Маленькая конкуренция на огромной области применения — огромное лавэ $$$. Вот это и есть истинная причина использовать кресты — возможность срубить €€€.

Честно говоря, «хитрый план» мне уже очень надоел, поэтому пора открыть карты.

Заодним, крестопоклонники смогут выйти на последний и решительный бой, т.к. сегодня пятница и вечером будет время пообщаться. Поклонникам мамкиного борща тоже наверняка есть что добавить, конструктивно и аргументированно.

Вот этот список:

  1. Вырвиглазный синтаксис и контекстно-зависимая грамматика
    • медленная компиляция
    • частые «internal error» в компиляторах
    • код плохо читается и его сложно поддерживать
    • разбор кода различными инструментами, вроде IDE, и его генерация - сильно затруднены
  2. ручное управление памятью
    • неудобства при работе с динамической памятью
    • утечки памяти
    • висячие ссылки
    • сегфолты
    • стандартные средства, как то malloc/new, работают медленно
    • фрагментация кучи
    • велосипедные аллокаторы на каждом шагу
      • которые далеко не факт что эффективнее malloc/new

    • велосипедные счетчики ссылок на каждом шагу, опять же
      • медленная работа
      • перерасход по памяти

    • отладка затруднена
    • написание GC, по факту, невозможно, отчасти из-за (5), (7) и (8)
  3. Никакого ABI
  4. Нестандартизированный и непредсказумый name mangling
  5. Дублирование функционала Си
    • сами фичи из Си никуда не деваются при этом
      • отчасти из-за того, что по функционалу превосходят аналоги из C++

    • запутывает новичков
    • malloc - new/new[], free - delete/delete[]
    • препроцессор - шаблоны
    • указатели - ссылки
      • ссылка не может быть NULL, что способствует появлению висячих ссылок и сегфолтов

    • структуры - классы
    • stdio - iostream
  6. Стандартная библиотека убога
    • Отсутствует даже такой функционал, как вменяемая работа со строками и многомерные массивы
      • Юникод?

  7. Слабая типизация
    • способствует ошибкам
    • затрудняет отладку
    • const не дает абсолютно никаких гарантий
    • при этом система типов невероятно переусложенена
      • в основном из-за пунктов (2), (5) и (9)
      • медленная компиляция
      • частые внутренние ошибки в компиляторах

  8. объектая система убога
    • практически никакой интроспекции
      • отладка затруднена
    • передача объектов по значению
      • понятие идентичности объекта теряет смысл
      • добавляет сложностей в управлении памятью
      • добавляет сложностей при отладке
      • используется часто, по причине (2)
        • перерасход по памяти
        • медленная работа

    • множественное наследование неудобно в использовании
      • проблема ромба по дефолту не разрешается никак

    • исключения в конструкторах гарантированно влекут утечку памяти
      • исключения в деструкторах тоже, и просто утечку - еще в лучшем случае
        • коды ошибок деструкторы и конструкторы возвращать не могут
          • ошибки в них не обработать никак
            • поэтому ими стараются не пользоваться
              • раздувание кода

    • деструктор можно вызывать до выхода из блока кода, или до delete
      • гарантированная утечка ресурсов/сегфлот
      • это не предотвратить никак, деструктор обязан быть public

    • одиночная диспетчеризация
      • виртуальные методы в конструкторах не работают
      • реализована убого
        • pure virtual function call
        • сложности в случае с множественным наследованием
        • деструкторы обязаны быть виртуальными
          • по дефолту - не виртуальные

        • никаких интерфейсов, только классы

    • порядок инициализации статических членов классов не определен
    • private, public и protected не дают никаких гарантий сокрытия данных
      • к инкапсуляции же не относятся совершенно никак

    • отсутствие «свойств»
      • вынуждает городить getter'ы и setter'ы
        • раздувание кода
        • размывание интерфейса класса

    • неявно генерирумые конструкторы, деструкторы и операторы присваивания
    • «friend» нарушают инкапсуляцию
  9. шаблоны
    • очень сильно замедляют компиляцию
    • раздувание кода
    • обфускация кода
    • результат раскрытия плохо предсказуем
    • сложности в отладке
      • километровые и плохо читаемые сообщения об ошибках при компиляции

    • нарушают инкапсуляцию
      • обязаны содержать реализацию в заголовочных файлах

    • позволяют генерировать некорректный код
  10. исключения
    • отсутствие finally/unwind-protect
      • заставляет городить классы ради одних деструкторов
        • раздувание кода
        • медленная компиляция
        • медленная работа

    • конфликтуют с другими возможностями языка
      • конструкторы/деструкторы
      • ручное управление памятью

    • работают медленно
    • малофункциональны (ср. CL condition system)

По причинам 3, 4, 5, 9 и 10 C++ совершенно неприменим для системного и низкоуровневого программирования. А по причинами 1, 2, 5, 6, 7, 8, и, опять же, 9 и 10 - и для прикладного.

У C++ нет области применения.

★★★★☆

Последнее исправление: stevejobs (всего исправлений: 1)

Ответ на: комментарий от qulinxao

получаем выбор конкретного метода по типу.

Разве это когда-то было проблемой? Можно с десяток разных алгоритмов реализовать с подобной функциональностью.

именно , что позднее связывание.

Да,да, «позднее связывание». Вот только такого понятия нет в «сишной» терминологии. «Late binding» это то, что предоставляет среда рантайма. Это принято так называть. То, что это можно навелосипедить - само собой разумеется.

dvl36
()
Ответ на: комментарий от metadeu5

У нас приложение написано на C, C++, bash. На bash генерится куча С++, С, html, sql кода. На С написана низкоуровневая часть типа всяких очередей, статистики, работа с базами, датами. Из уровня приложения на С - DAO, модули для nginx.

На С++ написана логика приложения, парсинг пакетов. И это реально удобно.. Удобно пользоваться std::string, vector итд. Удобно, что у нас куча енумов и нет возможности присвоить неправильное значение. Да даже IDE дает подсказку, какой метод есть у класса.

vromanov ★★
()
Ответ на: комментарий от anonymous

Лавсанчик, в отличие от остальных недоумков, хотя бы является настоящим программистом и зарабатывает программированием хоть и маленькую, но денежку. Так что уже не борщехлеб. Далеко пойдет, если не оступится.

anonymous
()
Ответ на: комментарий от dvl36

«Late binding» это то, что предоставляет среда рантайма.

тяжело жить с такими терминопониманиями.

Late binding, or dynamic binding,[1] is a computer programming mechanism in which the method being called upon an object is looked up by name at runtime.

зогбавно в русской вике статья из времён «ранних 60ых в нии мухосранска»

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

qulinxao ★★☆
()
Ответ на: комментарий от ckotinko

линковка везде одна и та же. именно она и тормозит старт

Тут вообще не про линковку разговор вели. А еще она бывает статическая.

dvl36
()
Ответ на: комментарий от dvl36

и? в данный момент в разрезе ооп objC какбе культурней С++ ( при том, что С++ как кобмайн круче objC)

а упращая objС есть С+ конкретный рантайм и макрорасширитель [] - и ты ведь не утверждаеш, что в рантайме objC( который (если не обращать внимания на яблолокин) строго расширяет С ) нет позднего связывания?

т.е при наличии «библиотеки» обязательной к использованию в группе Сразработчиков вполне есть позднее(ну и что, что велосипедное и ih) связывание.

в конце концов редактор языком(стандартом или референсом каким) не определён , и чё? на этом основание только cat?

qulinxao ★★☆
()
Ответ на: комментарий от Pinkbyte

Где это у него проблемы со стандартом? У D есть TDPL, формальная грамматика, удобный фронтенд, которым все пользуются. Да, огромный бюракротический орган отсутствует, но D прекрасно живет и без него. Ситуация с совместимостью явно лучше чем у C++.

Компилятор стандартный старый и оттестированный. Есть новый для GCC, еще не доделан, да.

uhbif19
()
Ответ на: комментарий от qulinxao

и ты ведь не утверждаеш, что в рантайме objC(

Не утверждаю ибо с objC не знаком.

вполне есть позднее(ну и что, что велосипедное и ih) связывание.

В таком случае можно говорить что в C есть объекты и методы, связанные списки и хеш-таблицы, строки и итераторы, etc. Навелосипедили много всякого. Глянь на glib/gObject.

dvl36
()
Ответ на: комментарий от dvl36

да. в си (ибо тьюринг :) )всё есть - и даже вполне переносимо в отличии от basic peek|poke :) /

у С++ в момент своего распространения было ровно то преимущество , которое в некотором смысле повторили в Жабе:

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

но так как некоторые оптимальные компромиссы -X лет назад перестали быть оптимальными -Y лет назад то добавлялись в С++ новые компромиссы - в итоге офигеный гримуар полное знание которого гарантирует «быть милионером»

qulinxao ★★☆
()
Ответ на: комментарий от dvl36

Которое вы реализуете. Обычно это делают через структурки с указателями на функции. Плюсовые виртуальные методы примерно так и реализованы. Как быстрее?

anonymous
()
Ответ на: комментарий от metadeu5

Почитайте автора ZeroMQ, хотя бы, вполне себе объективные причины.

Ссыль? Ну или сюда список причин можно...

anonymous
()
Ответ на: комментарий от uhbif19

У D сборщик хреновый. И тормозной. И не отключаемый по-настоящему... И вообще язык столь же сложен, как и С++. Какой-либо существенной разницы в плане продуктивности создания проектов я не заметил. Как и в объеме кода. D чуть медленнее и чуть хуже обрабатывается напильником.

В общем, польза-то от перехода какая?

anonymous
()
Ответ на: комментарий от anonymous

Обычно это делают через структурки с указателями на функции.

Да, и это будет работать, пожалуй, быстрее чем через vtable, как это реализовано в «плюсах».

dvl36
()
Ответ на: комментарий от dvl36

Почему? На практике это работает иногда даже чуть медленней. Опять же по причине больших возможностей по оптимизации у компилятора. Компилятор знает о vtbl. И даже больше - он их и создает. gcc с O3 и lto, в принципе, встраивает некоторые виртуальные вызовы. И делает это гораздо лучше, чем в случае ручных указателей на функции.

anonymous
()
Ответ на: комментарий от anonymous

Вы намеренно тролите, и хотите ввести в заблуждение не смотревших D.

D по ряду вопросов (списки, типизация, CTFE, контракты), по удобству рвет питон. Сравнивать его с C++ даже не смешно.

uhbif19
()
Ответ на: комментарий от anonymous

Сборщик давно обещают, вроде как скоро приготовят (:

uhbif19
()
Ответ на: комментарий от uhbif19

D по ряду вопросов (списки, типизация, CTFE, контракты), по удобству рвет питон.

А вот это смешно. Может быть нужно добавить примеров?

Сравнивать его с C++ даже не смешно.

А с чем его еще сравнивать, если это тот же С++, только с боку?

anonymous
()
Ответ на: комментарий от anonymous

gcc с O3 и lto, в принципе, встраивает некоторые виртуальные вызовы.

Если встроит(inline) метод, то, вызов _этого_ метода, видимо, будет быстрее. Нужно только добавить проверку того, что метод не был заменен на другой. Если не встроит, то вызов, по идее, должен получаться медленнее, из-за бОльшего количества indirection-ов. Вызовы перегруженных методов соответственно тоже не будут быстрыми.

И делает это гораздо лучше, чем в случае ручных указателей на функции.

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

dvl36
()
Ответ на: комментарий от dvl36

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

Омг, аж на один indirection больше. Вы так уверены, что это окажет больший эффект, нежели необходимость каждый раз вытаскивать vtable конкретного объекта в кеш?

ilammy ★★★
()
Ответ на: комментарий от ilammy

необходимость каждый раз вытаскивать vtable конкретного объекта в кеш?

Какой такой vtable?

Кто-то что-то не правильно распарсил.

dvl36
()
Ответ на: комментарий от dvl36

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

За вызов по ручному или виртуальному плюсовому ничего сказать не могу. Но вызов функции по указателю очень быстро работает. У интеля все мат функции реализованы через диспетчер, который выбирает исходя из cpuid при первом вызове. Ассемблер мне таки пришлось почитать ;)

ebantrop
()
Ответ на: комментарий от dvl36

Сам вызов по «ручному» указателю должен бы быть быстрее, чем через vtable.

С чего вдруг? У нас есть указатель на vtbl в объекте и есть известное значение смещения. Соответственно, никакого дополнительного уровня косвенности тут нет.

anonymous
()
Ответ на: комментарий от dvl36

Ну я так понял, что у тебя есть вот такая кучка функций (фактически, vtable):

struct ISomething {
    void (*foo)(void*, int);
    bool (*bar)(void*, float);
};
И ты утверждаешь, что вставить эти функции напрямую в объект:
struct A {
    struct ISomething something_methods;
    // ...
};

// ...

struct A *obj = make_A();
obj->something_methods.foo(obj, 100);
будет быстрее и шелковистее, чем сделать одну общую табличку для всех A:
struct A {
    struct ISomething* something_methods;
    // ...
};

ilammy ★★★
()
Ответ на: комментарий от anonymous

У нас есть указатель на vtbl в объекте и есть известное значение смещения.

object->vtbl+offset->method()

vs

object->method()

Я, пользуясь терминами статьи на lwn.net, говорю про «Directly embedded function pointers». Под «ручными» указателями вроде бы это подразумевается в дискуссии.

dvl36
()
Ответ на: комментарий от ilammy

есть вот такая кучка функций (фактически, vtable)

Не, никакой кучки. «Directly embedded function pointers». См. ответ выше.

dvl36
()

Когда этот вброс тлько полявился его очень конкретно расписал под хохлому замотиватор, недавно это сделал еще udpn, а после появления этого поста на жуйке у @Chtulhu родился такой текст:

Пацаны, я тут короче сидел за монитором и попытался скомпилить какую-то шнягу из буста, не помню какую, но внезапно компилятор сказал мне «интернал еррор» много раз. И тут я вдруг задумался — какое же говно c++! <[ апплодисменты в зале ]>

Представляете, пацаны, он дает мне stdio и iostream, и я должен выбирать. А как я выберу, это же так сложно, прямо глаза разбегаются! А вдруг я использую и первое, и второе? Совсем беспредел же получится, пацаны, видите какой говно-язык? <[ зал продолжает рукоплескать ]>

А стандартная библиотека? Она же просто ужасна! Там даже строки кривые — не спрашивайте почему, я не знаю^W^W^Wэто же очевидно! И знаете, скажу вам по секрету, я открыл ее исходник... Да, исходник самой stl! Вот вы когда-то смотрели туда? Вижу по глазам, что не смотрели. А я вот посмотрел, и ничего там не понял!!! <[ Бурное проявление недовольства в зале, апплодисменты, крики «Страуструпа на мыло!» ]>

Вот смотрите сюда, пацаны. Я нашел кусок кода, в котором используются макросы с шаблонами, конструкторы бросают исключения, написана куча велосипедных аллокаторов, память течет как из ведра. Я читал его и ужасался, на каком же говно-языке все вокруг пишут! <[ Одинокий голос из зала «а может ты сам написал этот код?», раздается несколько ударов, несогласного выносят ]>

И инкапсуляция у них нарушается всегда!!! В только представьте, пацаны — они спят и видят, как бы ее нарушить! Просыпаются, и сразу же бегут ее нарушать; засыпают, мечтая о том, как пойдут нарушать ее завтра! <[ Дамы в зале утираются платочками, всхлипывая; мужчины сидят с каменными лицами, сцепив зубы ]>

И вообще, самое страшное — этот подлый язык заставляет меня думать! Думать над освобождением памяти, думать над нормальной иерархией классов, думать над всем!!! Так дальше продолжаться не может — пора закопать его! За-ко-пать!!! Такое говно не должно оскорблять своим существованием наш священный мирок! Кто со мной?!

<[ Все, сидящие в зале, вскакивают, словно распрямившаяся пружина, и выбегают в дверь следом за лидером. Кажется, старому язычку пришел пиздец. Армия скрывается в тумане, некоторое время оттуда слышатся крики «Батт-хёрт! Батт-хёрт! Батт-хёрт!», под которые марширует этот карательный отряд, потом и они затихают вдали ]>

Из потайной дверцы в опустевший зал входит Александреску, вертя в руках блокнот. «2011 год, реактивное говно-нашествие школоты номер 9681», записывает он туда; выходит из зала, запирая дверь на ключ. На крыльце его поджидает Страуструп, они заходят в соседний паб, заказывают по кружке темного пива, и с улыбкой смотрят на экран на стене.

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

«больше двадцати лет прошло, и все повторяется», — со вздохом говорит Бьёрн, потягивая пиво.

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

«Пацаны...», — начинает свою проповедь очередной мессия.

Maledictus
()
Ответ на: комментарий от dvl36

object->method()

Это не то. У тебя будет каша из методов и полей в каждом объекте. Т.е. каждый объект будет содержать еще и поля с указателями на методы(не смотря на то, что они одни и те же у всех объектов одного класса).

На практике структурку с методами выделяют или совсем в отдельную сущность(которая будет передаваться в функции отдельным параметром - получаем «одноуровневый» ad-hoc полиморфизм, чем-то похожий на тайпклассы Haskell, но без контроля со стороны компилятора) или делают точно такой же указатель на vtbl/«объект-класс».

anonymous
()
Ответ на: комментарий от anonymous

У тебя будет каша из методов и полей в каждом объекте.

Никакой каши.

struct object {
// Data
 data1_t data1;
 data2_t data2;
// Methods
 method1_ret_t (*function1)();
 method2_ret_t (*function2)();
};
Все коротко, ясно и понятно. Pure C way, IMO.

Т.е. каждый объект будет содержать еще и поля с указателями на методы(не смотря на то, что они одни и те же у всех объектов одного класса).

Каждый объект будет содержать только указатели на те методы, которые ты собираешься перезагружать. Соответственно в каждом экземпляре класса(структуре) могут быть указатели на разные методы(функции). Если метод общий для всех экземпляров класса, делается обычная функция, аргументом в которую указатель на структуру(объект).

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

dvl36
()
Ответ на: комментарий от dvl36

Каждый объект будет содержать только указатели на те методы, которые ты собираешься перезагружать.

Нет. Он должен будет содержать все.

Все коротко, ясно и понятно.

Создай 100500 объектов и получи 100500 лишних наборов дублирующих друг друга указателей.

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

anonymous
()
Ответ на: комментарий от dvl36

Если метод общий для всех экземпляров класса, делается обычная функция, аргументом в которую указатель на структуру(объект).

Ты запутался, как мне кажется. Давай на примере. Покажи, как ты будешь представлять аналог:

class A
{
public:
    explicit A(int x)
        : m_x(x)
    {
    }

    int foo()
    {
        return m_x;
    }

    virtual int f()
    {
        puts("A::f");
        return m_x;
    }

    virtual int g()
    {
        puts("A::g");
        return m_x;
    }

    virtual int h()
    {
        puts("A::h");
        return m_x;
    }

private:
    int m_x;
};

class B : public A
{
public:
    B(int x, int y)
        : A(x),
          m_y(y)
    {
    }

    virtual int f()
    {
        puts("B::f");
        return A::f() + m_y;
    }

    virtual int g()
    {
        puts("B::g");
        return m_y;
    }

    virtual int h()
    {
        puts("B::h");
        return m_y;
    }

private:
    int m_y;
};

anonymous
()
Ответ на: комментарий от anonymous

У питона ужасная типизация, нет Emum-ов - это две самые бесящие меня вещи в веб-деве. Контрактное программирование очень нужно в питоне, хотя-бы из-за той же идиотской типизации и еще для многих вещей. Итераторы в D функциональнее, но это уже не так принципиально. Есть нормальные интерфейсы, что замечательно, вообще ООП очень понятное и без идиотских хаков, как на питоне.

Понятно что в основном (библиотека, list comprehension, генераторы, гринлеты) емы до питона далеко, но все же.

А с чем его еще сравнивать, если это тот же С++, только с боку?

Я даже не знаю, как ответить. D предельно удобный и продуманый язык. В нем нет ни сложных стандартных хаков (как в сях) ни идиотских маразмов (как в Java), есть некоторые неприятные моменты, но ничего критичного.

Любой человек знакомый с C-подобным синтаксисом и каким-нибудь языком, через день запишет на D (даже я). Про C++ я могу лишь процитировать «Когда начал набирать популярность C++, я попытался прочитать про него книгу… До сих пор осталась вмятина на стене за пианино, куда я ее швырнул в порыве гнева!».

Простейший пример: темплейты. В D это просто функции выполняющиеся при компиляции, с немного другим синтаксисом. Все остальное идентично обычным функциям. Все.

Что такое темплейты C++?

И так во всем, абсолютно.

uhbif19
()
Ответ на: комментарий от uhbif19

В D это просто функции выполняющиеся при компиляции, с немного другим синтаксисом. Все остальное идентично обычным функциям. Все.

У вас какой-то свой D. Шаблоны там гораздо сложнее, чем в С++.

Вообще я смотрю вам очень понравился D. И это наверно хорошо, но я такого восторга не испытываю. По факту на написание программ на D тратится столько же времени и сил, чем на написание аналогичных программ на C++. Это вам не питон.

anonymous
()
Ответ на: комментарий от anonymous

Нет. Он должен будет содержать все.

Обоснуй. Зачем применять object->init(object) вместо init_object(object), если init у всех объектов одинаковый?

Но это плохое решение в большинстве случаев.

Мы здесь вроде не о простоте реализации.

И это... ОО головного мозга не всегда хорошо работает в программировании.

dvl36
()
Ответ на: комментарий от dvl36

Обоснуй. Зачем применять object->init(object) вместо init_object(object), если init у всех объектов одинаковый?

ОМГ. Вы вообще понимаете, что такое позднее связывание? У вас может быть 100500 объектов с одним foo и еще 100500 с другим. При этом остальные функции, например, у них будут совпадать полностью.

Т.е.

int f(my_object_t *obj)
{
    obj->foo(obj);
    obj->bar(obj);
}

Должен работать с объектами обоих видов(«классов»)

anonymous
()
Ответ на: комментарий от anonymous

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

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

Что сложного в темплейтах D?

uhbif19
()
Ответ на: комментарий от uhbif19

Решил кстати попробовать послать патч в phobos (std в D), в течении месяца соберусь с силами, и отпишусь как оно. (Это кстати, к вопросу о Питоне.)

uhbif19
()
Последнее исправление: uhbif19 (всего исправлений: 1)
Ответ на: комментарий от anonymous

Это риторический вопрос. Я к тому, что это адская, отдельная сущность.

uhbif19
()
Ответ на: комментарий от anonymous

Ты запутался, как мне кажется.

Возможно, очень мало спал.

Давай на примере. Покажи, как ты будешь представлять аналог:

Я не использую C++, с синтаксисом, семантикой и используемой терминологией знаком слабо. ОО-шные «кунштюки» почти не использую, только по необходимости.

dvl36
()
Ответ на: комментарий от uhbif19

в D, даже в минорных релизах, ломают больше чем за всю историю С++, достаточно посмотреть на changelog текущей версии 2.063:

http://dlang.org/changelog.html

про революции в виде D1/D2/? и говорить не стоит, и пока ситуация не изменится - это будет ЯП только для фанбоев

wota ★★
()
Ответ на: комментарий от dvl36

И это... ОО головного мозга не всегда хорошо работает в программировании.

Мы тут о поздних связываниях и ad-hoc полиморфизмах, если что.

Не хотите ООП, давайте возьмем что-то вроде тайпклассов Haskell.

Делается это обычно как-то так:

/* typeclass */
typedef struct my_typeclass {
    int (*foo)(void *);
    int (*bar)(void *, int x);
} my_typeclass_t;
 
/* some function */
/* require typeclass */
int
some_fun(my_typeclass_t * instance, void * v1, void * v2)
{
    return instance->foo(v1) + instance->foo(v2);
}
 
/* some type 1 */
typedef struct my_type1 {
    int x;
} my_type1_t;
 
/* some type 2 */
typedef struct my_type2 {
    int y;
} my_type2_t;
 
/* instance of my_typeclass by type1 */
int
type1_foo(void *self)
{
    return ((my_type1_t*)self)->x;
}
 
int
type1_bar(void *self, int x)
{
    return ((my_type1_t*)self)->x + x;
}
 
static my_typeclass_t my_type1_instance_my_typeclass = {
    &type1_foo,
    &type1_bar
};
 
/* instance of my_typeclass by type2 */
int
type2_foo(void *self)
{
    return ((my_type2_t*)self)->y * 2;
}
 
int
type2_bar(void *self, int x)
{
    return ((my_type2_t*)self)->y * x;
}
 
static my_typeclass_t my_type2_instance_my_typeclass = {
    &type2_foo,
    &type2_bar
};
 
int
main()
{
    my_type1_t v1, v2;
    v1.x = 10;
    v2.x = 100;
 
    some_fun(&my_type1_instance_my_typeclass, &v1, &v2);
}

anonymous
()
Ответ на: комментарий от anonymous

У вас может быть 100500 объектов с одним foo и еще 100500 с другим. При этом остальные функции, например, у них будут совпадать полностью.

Ну и? Те, которые совпадают - object_foo(obj), те которые разные obj->bar(obj). Перезагрузка: obj->bar = &other_bar_function;

Я это уже писал, или анон читает только последний пост?

dvl36
()
Ответ на: комментарий от wota

Вот, это уже проясняет ситуацию. Хотя D1/D2 уже кончился.

uhbif19
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.