Реальный мир — это когда качество и новизна определяются распространённостью, да (специально для вас — это снова ирония).
Когда плюсовика в очередной раз тыкают в то, что его любимый язык — сборище вековых наслоений из костылей, он в ответ кроет последним универсальным аргументом: «зато популярно!»
То, что было сделано в C++ нашло широкое применение и показало благодаря этому что получилось хорошо
Окей. Открываю TIOBE — там питон на первом месте с трёхкратным отрывом от C++. Практика показывает, что экономия байтиков и микросекунд никому не нужна, и питон лучше, полезнее и качественнее, чем C++. Питон — лучший язык с ведущим подходом к безопасности (проверять типы во время выполнения куда лучше проверок во время компиляции, ведь там больше информации о контексте), наилучшим балансом производительности программиста и результирующего ПО, и самым богатым множеством библиотек. Подход питона к многопоточности показал, что форкать интерпретатор — эффективнее и быстрее всего, а треды в рамках одного процесса никому не нужны.
С++ (особенно современный) по-прежнему никому не нужен, кроме узкого загончика посетителей конференций, которые там занимаются интеллектуальной мастурбацией на никому не нужные монады, обсуждая, зачем их добавили в std::optional , скажем.
Определение полигона требует массовости применения? Да/нет.
Если бы была востребована только совместимость с Си, то шаблоны в C++ никто бы не использовал.
Что за бредовая логика?
Если нужна совместимость с C, то выбирают язык, где эта совместимость даётся проще всего, не более. Требований на (не)использование других возможностей выбранного языка это не накладывает.
И в рамках C++ эта реализация параметрического полиморфизма полностью и многократно доказала свою состоятельность.
Тут скорее вопрос в том, зачем с ООП работать с такими иерархиями. Я вам пример без ООП привёл, он точно не на ассемблере. Вопрос в том, что вам в нём конкретно не нравится (а не в соломенных чучелах и ложных дихотомиях «без ООП ⇒ на ассемблере»).
Нет. Меня интересуют инструменты, которые широко применяются на практике, которые можно брать и использовать. C++ стал таким инструментом.
Только тут полигоны (о которых шла речь изначально) ни при чём.
Кому-то параметрический полиморфизм в C++ может казаться чем-то (или не казаться), но история показала, что это было востребовано и широко использовано. В отличии от.
Востребована и широко использована была совместимость с C, не более.
А то так сейчас дойдём до того, что востребовано и широко использовано UB в каждой второй строчке и remote code execution от попытки склеить две строки.
И все равно у одного из них моделька однажды дернется и скажет, что нужно 429496728 акций купить (здесь на десятичный порядок меньше, чем числа, которые можно интерпретировать, как возможно signed, и оттого все куда хуже).
Только в одном случае матожидание времени до наступления этого события — сто лет, а в другом — скажем, месяц. Что выберете?
А это ужасная идея по всем причинам. Вы не будете безусловно дробить операции о крупных сделках без обратной связи о цене в любом случае.
Вы хотите, чтобы я тут биржевой движок целиком написал в комментариях, что ли? Моя цель — проиллюстрировать, считайте, полупсевдокодом, почему «решение купить (uint)-10 акций» не обязано вот прям сразу стриггерить лимиты.
Долго уже мечтаю увидеть статью о том, почему HFT не миф, и в каких конкретных кейсах до оптимизации на одну наносекунду винрейт был 50%, а после - 50.001%.
Это всё на самом деле неважно: есть предложение по деньгам, есть требование определённых знаний, и как-то вот с людьми, этим требованиям удовлетворяющими целиком, как-то трудно.
Свобода - это когда тебя не принуждают (фрилансер свободнее, чем сотрудник корпорации)
Даже тут разные люди понимают под принуждением разное. Если я предлагаю вам что-то, что вы не хотите (ну там, не знаю, попрыгать голышом на камеру) за десять медианных зарплат, а вы за чертой бедности, то принуждаю ли я вас? Формально я лишь расширяю множество доступных вам вариантов и делаю вам строго лучше, но значимое число людей считает подобные вещи принуждением.
Формальное, теоретическое определение (Свобода- там где демократия, права человека, либерализм экономический и политический)...
Тут сначала придётся определить формально демократию и права человека.
Например, Поппер в «The Open Society and Its Enemies» определяет демократию в основном как возможность народа (бескровно?) сменить правительство. Окей, когда власть захватил тиран, отменил выборы и всё такое, вроде бы всё понятно: такой возможности нет (или есть? история знает примеры распавшихся «бескровно» тираний). Но когда де-юре есть выборы, Конституция, и так далее, и даже там кто-то что-то как-то считает на этих выборах — как тут с возможностью? Она есть, просто результаты мне или вам не нравятся потому, что ей не воспользовались и народ всё устраивает, или возможности на самом деле нет, а все «одобрямс» народа — нарисованные и дутые?
С правами человека всё ещё сложнее, потому что стандартные фразы про «свобода начинается где заканчивается» и прочие кулаки у носа — это не даёт конструктивного метода определения, что входит в множество прав, и, более того, разные юрисдикции, которые мы считаем более-менее равно свободными, по некоторым вопросам имеют диаметрально противоположные мнения. Единственный вывод — что права человека лишь вопрос общественного консенсуса, но тогда нельзя говорить о нарушении прав человека, покуда общество в своём демократическом большинстве не поднимает протесты против таких случаев «нарушения».
Начать можно, тащем, с пассажа про язык с точки зрения либертарианцев. Начиная от того, что в этом пассаже есть внутренние логические ошибки (если язык тоталитарный и даётся свыше, то как можно учить другие языки?), фактологические ошибки (язык не един даже в рамках одной страны/национальной сущности/етц), и заканчивая тем, что либертарианцы так, конечно, не считают.
Кстати, хороший у вас код, я php не знаю, но прям… $ary ?? $this->selected as $node, если я правильно понимаю, что делает, прямо классика ООП и абьюзинга абстракций.
Рисовать на хаскеле (и на любом другом чистом языке) клонирование бессмысленно, так что я ограничусь траверсалами. Для типа XmlNode выше, например, наиболее прямым аналогом вашего кода будет что-то вроде:
data Stage = Pre | Post deriving (Eq, Ord, Show)
data WalkEntry = WalkEntry { stage :: Stage, depth :: Int, node :: XmlNode } deriving (Eq, Ord, Show)
walk :: XmlNode → [WalkEntry]
walk = go [] 0 where
go acc depth node = WalkEntry Pre depth node : cont (WalkEntry Post depth node : acc) where
cont acc' | TagNode{..} <- node
, Just (_, next) <- unsnoc children = go acc' (depth + 1) next
| otherwise = acc'
Вместо $run_close результат аннотируется перечислением Pre или Post, и конкретное поведение с $run_close = false можно получить, например, как
Либо можно завернуться в произвольный моноид, и заодно одним walk описать не только получение списка нижних-правых, но и, скажем, элемент с самым большим числом детей, и так далее (если брать соответствующий моноид):
walk' :: Monoid m => (WalkEntry → m) → XmlNode → m
walk' inj = go 0 where
go depth node = inj (WalkEntry Pre depth node) <> mid <> inj (WalkEntry Post depth node) where
mid | TagNode{..} <- node
, Just (_, next) <- unsnoc children = go (depth + 1) next
| otherwise = mempty
На практике, конечно, я бы так не делал, а взял бы линзы для XML'я или JSON'а и тому подобного.
Дерево (например, бинарное, с объектами типа A только во внутренних узлах, и пустыми листьями) определяется как начальная алгебра функтора X ↦ 1 + X × A × X. Можно показать, что эта алгебра — изоморфизм, поэтому на самом деле вы имеете равенство (окей, изоморфизм, но изнутри теорката их отличить тяжело) T = 1 + T × A × T.
С таким подходом проблемы будут независимо от языка.
С каким — таким? «Посмотреть предложенный собеседником код и найти там проблемы»?
Проблемы с предложенным вами подходом потому, что он нелокален. Ну, вернее, это проблема не вашего подхода, а общей философии C++: например, если вы почитаете или послушаете гугловского Титуса Винтерса, топящего за что-то вроде «C++ design unit is an overload set» (а не функция или класс или модуль или…), и послушаете про его же кулстори про эволюцию гугловской кодовой базы, то увидите, что добрая часть проблем вылезает именно из-за этой нелокальности. Семантика, скрывающаяся за именем, оказывается размазана не по одному определению одной функции за этим именем, а по всему множеству всех функций с этим именем, потенциально в разных неймспейсах (привет ADL), и изменение этого множества приводит к забавным нелокальным спецэффектам (например, вопрос о роли requires вы почему-то пропустили — но я вас понимаю, сам бы его пропустил). Это — один из худших видов coupling'а.
Наверное, это не его забота, обеспечить приёмистость не точно соответствующих типов в предоставляемом API, — но только таких, которые разрешены проектировщиком API, а не любых, которые язык позволяет.
Наверное. Моей заботой (и вообще обязанностью) как программиста инфры было именно обеспечить максимально комфортную жизнь трейдерам, которые в статистике и прочих своих этих всех альфах-бетах разбираются куда лучше, чем в C++.
Есть предложенный механизм, и если хотеть добиться результата, этот механизм можно использовать для достижения этого самого результата.
Я с этим не спорю. Речь о другом: у предложенного механизма есть много негативных аспектов, поэтому говорить, что он эквивалентен решениям из раста (или из хаскеля — я так-то раст не люблю и хаскелист вообще), несколько нечестно.
Если не продумывать каждое решение, а пытаться наворачивать сверху, да побыстрее, а также быть вынужденным постоянно что-то менять, — да проблемы будут.
Как успехи с продумыванием кодовой базы на года вперёд?
Если у вас достаточно времени, то проще на том же хаскеле наваять для тех же трейдеров DSL с понятными сообщениями об ошибках, понятным поведением, понятным предметно-специфичным статическим анализом, и предсказуемой кодогенерацией. Да, проще, чем заставлять всех разбираться в экспоненциальной сложности C++.
Эта проблема не является специфичной для данного случая.
Ну, да. Но в этом случае она вылезает тоже.
Всё же, первая задача значительно проще, вы преувеличиваете.
Observationally equal. Я не знаю ни одного человека, решившего задачу останова, и не знаю ни одного человека, который бы знал C++. И, кстати, сверхвысокие HFT-шные зарплаты не позволяют их найти — все знатоки C++ в основном почему-то прячутся в комментариях на хабре или опеннете и тому подобных, вместо того, чтобы приходить на собеседования и получать свои заслуженные 500-700 в год.
Это, по всей видимости, не имеет отношения к реально происходившим событиям, потому что сделка была не одна большая, а — большое количество относительно мелких. И если бы ушло, то ордер был бы один.
Knight capital — это так, намёк на то, что при факапах в коде проверки и ограничители срабатывают не сразу, и даже их может оказаться недостаточно (они ж обанкротились и закрылись).
Так в коде выше на биржу уходит тоже большое число относительно мелких (если хочется, можете вместо sendOrder читать splitAndExecuteOrder или чё-т такое, сути это не меняет). Или вы думаете, что если вам надо купить/продать 100500 акций, то вы их покупаете одним пакетом? Это плохая идея по куче причин.
Ещё код по теме можно посмотреть в моём ответе
Ожидать, что люди будут в продакшене писать и поддерживать такой код — несерьёзно.
Потому что код меняется. Вчера const char* было, сегодня std::string_view (или наоборот). Вчера double price , сегодня fixed_point<4> price (в который неплохо бы конвертировать из литералов, кстати, но не будем вскрывать эту тему, перегрузки разбегаются как тараканы).
Вот я скопипастил ваш код (и заодно добавил requires из соседнего поинта) и сделал вид, что он эволюционирует со временем, «забыв» поменять тип первого аргумента в удалённой перегрузке:
Обратите внимание на -10. Задача со звёздочкой: скомпилится или нет? (ответ: да, скомпилится)
Теперь я убираю requires. Скомпилится или нет?
clang говорит «ambiguous» и ошибка, gcc компилирует (лан, моя вина — надо -pedantic добавлять), но говорит
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
13 | sendOrder("DAL", true, -10, 5.0);
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
Что за worst conversion? Откуда? Сможете сходу огласить весь список conversion'ов? Почему requires так влияет? Смогли бы предсказать такой результат, просто глядя на код? Сможете объяснить среднему программисту на C++, почему результат такой и причём тут requires? Сможете объяснить среднему трейдеру, который на C++ пишет постольку, поскольку вы ему даёте апишку для вашего инфра-кода, а у себя он там обмазывается q, матлабами и прочим?
Сможете быть уверенным, что сможете адекватно поддерживать кодовую базу на миллион-другой строк, где подобными финтами всё обмазано, и где простейшее изменение рискует превратиться в сутки-другие расхлёбывания выблева компилятора минимум, и где рекомпиляция одного TU занимает минуты даже в дебаг-билде, без оптимизаций? Мне приходилось поддерживать, не рекомендую.
И это — правда, та функция, адрес которой, весьма вероятно, необходимо будет брать?
Да, а что? std::bind_front(&sendOrder, "GOOG");
Сейчас там и так double последним аргументом. В таких местах float не используется.
Почему? Я хочу, чтобы у меня в кэшлайн помещалось 16 цен, а не 8 — почему вы мне запрещаете так делать?
Олсо, в таких местах и double не используется, а используется фиксированная точка, но неважно — это учебный пример.
В данной задаче это — необходимо?
Не, просто задача «освоить C++» примерно настолько же реализуема, как «решить проблему останова».
Вы, видимо, обознались.
Вовсе нет. Просто считать, что это число вот прям сразу пойдёт в пакетик на биржу — это несколько ошибочно. Там, например, может быть что-то по смыслу как
void sendOrder(...)
{
const int batchSize = computeSmallBatchSize(quantity);
for (int i = 0; i < quantity; i += batchSize) {
sendToExch(std::min(batchSize, quantity - i));
waitPriceToSettle();
}
}
И если вы хотите купить 10 акций, а случайно покупаете -10 = 4294967286, то до того, как у вас сработают всякие риск-чеки, дневные лимиты, и прочее, у вас уже уйдёт ордеров на сотню тыщ акций.
ML и параметрический полиморфизм. В C++ обкатывали разве что идею «как бы параметрический полиморфизм сделать максимально криво, но чтобы потом было весело делать головоломки и отсеивать людей на интервью». Хорошо разве что для job security.
Почему не было даже попыток применить данное решение?
Потому что вам теперь надо обновлять обе сигнатуры, и компилятор далеко не всегда напомнит вам это сделать.
Потому что теперь вы не можете взять адрес sendOrder(по крайней мере, в контекстах вроде аргумента для стандартных алгоритмов, где ожидаемый тип callable не фиксирован).
Потому что если вы захотите принимать doubleилиfloatпоследним аргументом, то вам уже придётся обмазываться концептами и писать что-то вроде requires (!(std::is_same_v<T3, double> || std::is_same_v<T3, float>)). Очень удобно и дружественно к людям, в чьи обязанности входит не только штудирование талмуда++. Кстати, тут крошка-джун пришёл к отцу, и спросила кроха: «папа, а что тут лучше, std::same_as или std::is_same_v? Какая вообще между ними разница? Какой-какой частичный порядок? Я полностью каждый день порядок навожу!»
следовало бы научиться пользоваться C++
И решить проблему останова на сдачу.
Человек, утверждающий подобное, даже не пытался изучить предмет.
Человек, отвечающий подробное, даже не понимает смысла учебных, иллюстрирующих примеров.
Реальный мир — это когда качество и новизна определяются распространённостью, да (специально для вас — это снова ирония).
Когда плюсовика в очередной раз тыкают в то, что его любимый язык — сборище вековых наслоений из костылей, он в ответ кроет последним универсальным аргументом: «зато популярно!»
Окей. Открываю TIOBE — там питон на первом месте с трёхкратным отрывом от C++. Практика показывает, что экономия байтиков и микросекунд никому не нужна, и питон лучше, полезнее и качественнее, чем C++. Питон — лучший язык с ведущим подходом к безопасности (проверять типы во время выполнения куда лучше проверок во время компиляции, ведь там больше информации о контексте), наилучшим балансом производительности программиста и результирующего ПО, и самым богатым множеством библиотек. Подход питона к многопоточности показал, что форкать интерпретатор — эффективнее и быстрее всего, а треды в рамках одного процесса никому не нужны.
С++ (особенно современный) по-прежнему никому не нужен, кроме узкого загончика посетителей конференций, которые там занимаются интеллектуальной мастурбацией на никому не нужные монады, обсуждая, зачем их добавили в
std::optional, скажем.Я всё правильно понял?
Вас интересуют только ложные силлогизмы и подмены тезиса, это я уже понял.
Определение полигона требует массовости применения? Да/нет.
Что за бредовая логика?
Если нужна совместимость с C, то выбирают язык, где эта совместимость даётся проще всего, не более. Требований на (не)использование других возможностей выбранного языка это не накладывает.
Как предмет для шуток, разве что.
Тут скорее вопрос в том, зачем с ООП работать с такими иерархиями. Я вам пример без ООП привёл, он точно не на ассемблере. Вопрос в том, что вам в нём конкретно не нравится (а не в соломенных чучелах и ложных дихотомиях «без ООП ⇒ на ассемблере»).
Только тут полигоны (о которых шла речь изначально) ни при чём.
Востребована и широко использована была совместимость с C, не более.
А то так сейчас дойдём до того, что востребовано и широко использовано UB в каждой второй строчке и remote code execution от попытки склеить две строки.
Молодые люди какие-то, старые… О требованиях к полигонам мы согласны в итоге или нет?
Только в одном случае матожидание времени до наступления этого события — сто лет, а в другом — скажем, месяц. Что выберете?
Вы хотите, чтобы я тут биржевой движок целиком написал в комментариях, что ли? Моя цель — проиллюстрировать, считайте, полупсевдокодом, почему «решение купить
(uint)-10акций» не обязано вот прям сразу стриггерить лимиты.Это всё на самом деле неважно: есть предложение по деньгам, есть требование определённых знаний, и как-то вот с людьми, этим требованиям удовлетворяющими целиком, как-то трудно.
Про необходимость массовости полигона была ирония. Извините, если получилось слишком неявно.
Вопрос о массовости вами задан не был? Ну ок (тоже ирония, если что).
А клонировать-то зачем? Я могу написать
и получить два одинаковых параграфа, без всякого явного клонирования.
Даже тут разные люди понимают под принуждением разное. Если я предлагаю вам что-то, что вы не хотите (ну там, не знаю, попрыгать голышом на камеру) за десять медианных зарплат, а вы за чертой бедности, то принуждаю ли я вас? Формально я лишь расширяю множество доступных вам вариантов и делаю вам строго лучше, но значимое число людей считает подобные вещи принуждением.
Тут сначала придётся определить формально демократию и права человека.
Например, Поппер в «The Open Society and Its Enemies» определяет демократию в основном как возможность народа (бескровно?) сменить правительство. Окей, когда власть захватил тиран, отменил выборы и всё такое, вроде бы всё понятно: такой возможности нет (или есть? история знает примеры распавшихся «бескровно» тираний). Но когда де-юре есть выборы, Конституция, и так далее, и даже там кто-то что-то как-то считает на этих выборах — как тут с возможностью? Она есть, просто результаты мне или вам не нравятся потому, что ей не воспользовались и народ всё устраивает, или возможности на самом деле нет, а все «одобрямс» народа — нарисованные и дутые?
С правами человека всё ещё сложнее, потому что стандартные фразы про «свобода начинается где заканчивается» и прочие кулаки у носа — это не даёт конструктивного метода определения, что входит в множество прав, и, более того, разные юрисдикции, которые мы считаем более-менее равно свободными, по некоторым вопросам имеют диаметрально противоположные мнения. Единственный вывод — что права человека лишь вопрос общественного консенсуса, но тогда нельзя говорить о нарушении прав человека, покуда общество в своём демократическом большинстве не поднимает протесты против таких случаев «нарушения».
Начать можно, тащем, с пассажа про язык с точки зрения либертарианцев. Начиная от того, что в этом пассаже есть внутренние логические ошибки (если язык тоталитарный и даётся свыше, то как можно учить другие языки?), фактологические ошибки (язык не един даже в рамках одной страны/национальной сущности/етц), и заканчивая тем, что либертарианцы так, конечно, не считают.
Кстати, хороший у вас код, я php не знаю, но прям…
$ary ?? $this->selected as $node, если я правильно понимаю, что делает, прямо классика ООП и абьюзинга абстракций.Рисовать на хаскеле (и на любом другом чистом языке) клонирование бессмысленно, так что я ограничусь траверсалами. Для типа
XmlNodeвыше, например, наиболее прямым аналогом вашего кода будет что-то вроде:Вместо
$run_closeрезультат аннотируется перечислениемPreилиPost, и конкретное поведение с$run_close = falseможно получить, например, какЛибо можно завернуться в произвольный моноид, и заодно одним
walkописать не только получение списка нижних-правых, но и, скажем, элемент с самым большим числом детей, и так далее (если брать соответствующий моноид):На практике, конечно, я бы так не делал, а взял бы линзы для XML'я или JSON'а и тому подобного.
Дерево (например, бинарное, с объектами типа A только во внутренних узлах, и пустыми листьями) определяется как начальная алгебра функтора X ↦ 1 + X × A × X. Можно показать, что эта алгебра — изоморфизм, поэтому на самом деле вы имеете равенство (окей, изоморфизм, но изнутри теорката их отличить тяжело) T = 1 + T × A × T.
С каким — таким? «Посмотреть предложенный собеседником код и найти там проблемы»?
Проблемы с предложенным вами подходом потому, что он нелокален. Ну, вернее, это проблема не вашего подхода, а общей философии C++: например, если вы почитаете или послушаете гугловского Титуса Винтерса, топящего за что-то вроде «C++ design unit is an overload set» (а не функция или класс или модуль или…), и послушаете про его же кулстори про эволюцию гугловской кодовой базы, то увидите, что добрая часть проблем вылезает именно из-за этой нелокальности. Семантика, скрывающаяся за именем, оказывается размазана не по одному определению одной функции за этим именем, а по всему множеству всех функций с этим именем, потенциально в разных неймспейсах (привет ADL), и изменение этого множества приводит к забавным нелокальным спецэффектам (например, вопрос о роли
requiresвы почему-то пропустили — но я вас понимаю, сам бы его пропустил). Это — один из худших видов coupling'а.Наверное. Моей заботой (и вообще обязанностью) как программиста инфры было именно обеспечить максимально комфортную жизнь трейдерам, которые в статистике и прочих своих этих всех альфах-бетах разбираются куда лучше, чем в C++.
Я с этим не спорю. Речь о другом: у предложенного механизма есть много негативных аспектов, поэтому говорить, что он эквивалентен решениям из раста (или из хаскеля — я так-то раст не люблю и хаскелист вообще), несколько нечестно.
Как успехи с продумыванием кодовой базы на года вперёд?
Если у вас достаточно времени, то проще на том же хаскеле наваять для тех же трейдеров DSL с понятными сообщениями об ошибках, понятным поведением, понятным предметно-специфичным статическим анализом, и предсказуемой кодогенерацией. Да, проще, чем заставлять всех разбираться в экспоненциальной сложности C++.
Ну, да. Но в этом случае она вылезает тоже.
Observationally equal. Я не знаю ни одного человека, решившего задачу останова, и не знаю ни одного человека, который бы знал C++. И, кстати, сверхвысокие HFT-шные зарплаты не позволяют их найти — все знатоки C++ в основном почему-то прячутся в комментариях на хабре или опеннете и тому подобных, вместо того, чтобы приходить на собеседования и получать свои заслуженные 500-700 в год.
Knight capital — это так, намёк на то, что при факапах в коде проверки и ограничители срабатывают не сразу, и даже их может оказаться недостаточно (они ж обанкротились и закрылись).
Так в коде выше на биржу уходит тоже большое число относительно мелких (если хочется, можете вместо
sendOrderчитатьsplitAndExecuteOrderили чё-т такое, сути это не меняет). Или вы думаете, что если вам надо купить/продать 100500 акций, то вы их покупаете одним пакетом? Это плохая идея по куче причин.Ожидать, что люди будут в продакшене писать и поддерживать такой код — несерьёзно.
Написано в фразе прямо перед процитированной вами, но я повторюсь: в ML (ранние 70-ые).
Более того, даже тот же хаскель (с ещё более полиморфным полиморфизмом) появился в том же 90-м.
Полигон — это когда массовое применение прямо там же, да.
Не двигайте гоалпосты.
Потому что код меняется. Вчера
const char*было, сегодняstd::string_view(или наоборот). Вчераdouble price, сегодняfixed_point<4> price(в который неплохо бы конвертировать из литералов, кстати, но не будем вскрывать эту тему, перегрузки разбегаются как тараканы).Вот я скопипастил ваш код (и заодно добавил
requiresиз соседнего поинта) и сделал вид, что он эволюционирует со временем, «забыв» поменять тип первого аргумента в удалённой перегрузке:Обратите внимание на
-10. Задача со звёздочкой: скомпилится или нет? (ответ: да, скомпилится)Теперь я убираю
requires. Скомпилится или нет?clang говорит «ambiguous» и ошибка, gcc компилирует (лан, моя вина — надо
-pedanticдобавлять), но говоритЧто за worst conversion? Откуда? Сможете сходу огласить весь список conversion'ов? Почему
requiresтак влияет? Смогли бы предсказать такой результат, просто глядя на код? Сможете объяснить среднему программисту на C++, почему результат такой и причём тутrequires? Сможете объяснить среднему трейдеру, который на C++ пишет постольку, поскольку вы ему даёте апишку для вашего инфра-кода, а у себя он там обмазывается q, матлабами и прочим?Сможете быть уверенным, что сможете адекватно поддерживать кодовую базу на миллион-другой строк, где подобными финтами всё обмазано, и где простейшее изменение рискует превратиться в сутки-другие расхлёбывания выблева компилятора минимум, и где рекомпиляция одного TU занимает минуты даже в дебаг-билде, без оптимизаций? Мне приходилось поддерживать, не рекомендую.
Да, а что?
std::bind_front(&sendOrder, "GOOG");Почему? Я хочу, чтобы у меня в кэшлайн помещалось 16 цен, а не 8 — почему вы мне запрещаете так делать?
Олсо, в таких местах и
doubleне используется, а используется фиксированная точка, но неважно — это учебный пример.Не, просто задача «освоить C++» примерно настолько же реализуема, как «решить проблему останова».
Вовсе нет. Просто считать, что это число вот прям сразу пойдёт в пакетик на биржу — это несколько ошибочно. Там, например, может быть что-то по смыслу как
И если вы хотите купить 10 акций, а случайно покупаете -10 = 4294967286, то до того, как у вас сработают всякие риск-чеки, дневные лимиты, и прочее, у вас уже уйдёт ордеров на сотню тыщ акций.
CLU.
ML и параметрический полиморфизм. В C++ обкатывали разве что идею «как бы параметрический полиморфизм сделать максимально криво, но чтобы потом было весело делать головоломки и отсеивать людей на интервью». Хорошо разве что для job security.
Здесь согласен.
Потому что вам теперь надо обновлять обе сигнатуры, и компилятор далеко не всегда напомнит вам это сделать.
Потому что теперь вы не можете взять адрес
sendOrder(по крайней мере, в контекстах вроде аргумента для стандартных алгоритмов, где ожидаемый тип callable не фиксирован).Потому что если вы захотите принимать
doubleилиfloatпоследним аргументом, то вам уже придётся обмазываться концептами и писать что-то вродеrequires (!(std::is_same_v<T3, double> || std::is_same_v<T3, float>)). Очень удобно и дружественно к людям, в чьи обязанности входит не только штудирование талмуда++. Кстати, тут крошка-джун пришёл к отцу, и спросила кроха: «папа, а что тут лучше,std::same_asилиstd::is_same_v? Какая вообще между ними разница? Какой-какой частичный порядок? Я полностью каждый день порядок навожу!»И решить проблему останова на сдачу.
Человек, отвечающий подробное, даже не понимает смысла учебных, иллюстрирующих примеров.
Knight capital, кстати, передаёт привет.
Зависимые типы помогут (и помогают).