• Хаброквест в честь 20-летия Mail.Ru Group — 20 задачек
    0
    А, там Й не хватает, а я Ё удалял, почти сошлось. Да, косякнули.
  • Хаброквест в честь 20-летия Mail.Ru Group — 20 задачек
    0
    Там в подсказках было строго указано чем расшифровывать. В общем-то даже расшифровывается, если убрать из массива с алфавитом букву «Ё».
  • Хаброквест в честь 20-летия Mail.Ru Group — 20 задачек
    –3
    Вы наркоманы накосячили с шифром Цезаря! Хорошо ещё я подбирал с учётом того, что может не быть буквы Ё, вы её куда в алфавите поставили? Или вы по коду буквы сортировали?!
  • Хаброквест в честь 20-летия Mail.Ru Group — 20 задачек
    0
    Квест — супер! Спасибо большое!
  • Как собеседует Google: чему быть, чего не миновать
    –1
    Но ведь все сервисы гугла уже написаны чуть более чем полностьью и на поддержке стоят ключевые люди. Зачем вам новые, чтобы ковырять и поддерживать то, что никто из своих не берёт?
  • Java 11 / JDK 11: General Availability
    +2
    Умри, CORBA, в мучениях!
  • Как Яндекс применил компьютерное зрение для повышения качества видеотрансляций. Технология DeepHD
    0
    Отличная статья, спасибо большое, было очень интересно!
  • Как может вызваться никогда не вызываемая функция?
    –6
    Ну, если вы пишете бизнес-логику на плюсах, то это уже клиника. Сорян. Лайнер выглядит лайнером, только размерами кодовой базы. Простые операции с коллекциями — ад, простейшие операции с текстом в Юникоде — ад. Не в той вы рыбацкой лодке.
    Что до проекта, если вы в России, то скорее всего ваша компания почти наверняка сдаёт всю отчётность нашему государству через код на С++/Python.
    С распределением нагрузки (перед 1-м апреля нагрузка будь здоров), с кучей воркеров, асинхронностью, и всем тем, что вы называете синтаксическим сахаром, дабы не дать разработчику моей позапрошлой компании ошибиться хоть где-либо.
    Это вам не по вектору итераторы гонять. :)
    P. S. Думайте и дальше, что на Python какие-то рыбацкие лодки, а на C++ можно построить что-то исключающее фатальные ошибки. При всех ваших косяках архитектуры можете обвинять криворукого пользователя, который чего-то там недопрочитал. Удач.
  • Как может вызваться никогда не вызываемая функция?
    –1
    Ну если Вы предпочитаете Хаскель Питону, то мне даже сказать нечего. Удачи в том, что Вам точно мозги прочищает. Тут явно не прочистка нужна.
    Что до того, что clang работает быстрее, он хорош пока работает номально. Сюрпризов он выдаёт немало, а в продакшене сюрпризы строго противопоказаны.
  • Как может вызваться никогда не вызываемая функция?
    0
    Ну начинаются стандартные отмазы: для тяп-ляп разработки, для наколенных приложений, синтаксический сахар, язык не язык, платформа не платформа. Дабы не быть голословным, я создал распределённую систему для написания методов бизнес-логики на Python ещё в 2011 году, до сих пор без меня прекрасно работает, поддерживаемая и со стороны ядра на C++, и со стороны Python большинство разработчиков. Зато не так давно загнулась крупная разработка, где ребята, закончившие мехмат наговняжили на C++ огромную нерабочую систему. Ведь на C++ куда проще накосяпорить, если нет понимания. И не будет понимания, пока не с чем сравнивать. Нужна крупная понятно написанная до очевидного система. Возьмите код Django. Даже не обязательно Python, возьмите AR на RoR, тоже отличная система. Потом посмотрите на ваш код, сравните и ужаснитесь. У меня всё.
  • Необразованная молодёжь. Ответ бизнеса
    +2
    Ну не, если за 5 лет от вас не ушёл вообще никто, то вы и правда сказочная страна Оз. Тогда ваш опыт уникален, но применим только к вам. В любом крупном городе большинство контор довольно активно нанимают спецов, потому что так же активно теряют, в том числе за бугор (последнее время эпидемия).
  • Необразованная молодёжь. Ответ бизнеса
    –3
    В C/C++ так же как и в Delphi операции с невалидными указателями (через ^) уронят процесс.
  • Необразованная молодёжь. Ответ бизнеса
    +1
    Вы только не обижайтесь, но Вы демонстрируете весьма негибкий подход к набору специалистов. Скажите честно, сколько по-настоящему крутых спецов ваша компания наняла за последние пару лет. В соотношении с тем количеством спецов, что от вас ушли.
    Была такая компания, и не одна, которая растила узконаправленных спецов со студенческой скамьи, которые писали соответствующий код. В результате сформировалась весьма специфическая атмосфера, идеи и код по эволюционному развитию аналогичный Австралии по отношению к остальному миру. И разумеется до пуфиков они доросли только тогда, когда позвали хороших спецов со стороны,
  • Как может вызваться никогда не вызываемая функция?
    –2
    Ну не сказал бы я, что он прям уж работает. Претензий к нему стабильно больше, чем к GCC и MSVC, пока он на уровне «так себе поделка». Данный пример, с вашим комментарием
    Вопрос в другом: а хочу ли я, чтобы он так делал? И в моём случае ответ однозначен: да, разумеется.

    однозначно определяет дальнейшее развитие продукта в сторону наиболее косячную с итераионным развитием в сторону «ну да, неочевидно, странно, но зато оптимизировано в другом месте». Подход весьма скоро приведёт Вас к взрослению, когда пезанская башня начнёт очень сильно наклоняться.
    Для сравнения подходов, крайне рекомендую покодить полгодика-годик на том же Python 3.x, весьма освежает подход к очевидному и понятному и заставляет по-другому взглянуть на свой код на C++.
    Также было бы полезно попрактиковаться в Boost.Python, там всё сделано для удобства пользователя, каким бы программистом он ни был. Сравните подход, его аккуратность и очевидность происходящего в процессе написания кода.
  • Как может вызваться никогда не вызываемая функция?
    –4
    Да нет, уважаемый коллега, я весьма неплохо орудую C++, крайне неплохо, рискую показаться грубым, но я бы поумерил ваш пыл в мою сторону, однако, как и любой пользователь, я люблю такого же уважительного отношения ко мне как к пользователю, какое проявляю сам к пользователям моих систем. Если пользователю моего продукта что-то неочевидно, виноват я, так и тут, очевидно, что шланг ведёт себя крайне неестественно и оптимизацией подменяет наиболее очевидное поведение. Можно сколько угодно прикрываться стандартом, тут это шлангу никак не помогает.
  • Необразованная молодёжь. Ответ преподавателя-совместителя
    0
    Я знаю, что ты из Parallels. ;) Это оттуда перл.
  • Как может вызваться никогда не вызываемая функция?
    –7
    Ещё раз повторяю, любое неочевидное поведение продукта, который вводит пользователя продукта в глубокий ступор — бесспорное багло. В данном случае очевидное донельзя. Отрицая это, Вы ставите себя в весьма глупое положение.
  • Как может вызваться никогда не вызываемая функция?
    0
    Ну-ну, незачем быть настолько агрессивным, отстаивая правильность поведения при «неопределённом поведении». Фактически компилятор ведёт себя максимально неочевидным способом. В точности нуль разработчиков ожидает то, чего они получат и никого это не устроит. Детали реализации пользователей компилятора не волнуют, как и ваши проблемы с некими программистами, выросшими на Java, храни их боже.
  • Как может вызваться никогда не вызываемая функция?
    –7
    Давайте честно скажем, что в шланге багло, несмотря на Undefined behavior, компилятор берёт на себе излишне много.
  • Здравствуй, Хабр
    0
    О! Тензор на Хабре! Наконец-то!
    Вам, ребята, можно долго и интересно рассказывать о своём технологическом стеке, о гибкости перехода от одной технологии к другой и разноуровневой разработке.
    Вы однозначно лучшие из всех, с кем я когда-либо работал! Так держать!
    Сам там когда-то руководил отделом Ядра Платформы, а до этого оптимизировал систему распределения памяти при вычитывании результатов SQL-запросов и внедрял связку C++/Python, результатом чего в том числе стал цикл статей на Хабре и в журнале «Хакер» про Boost.Python.
    Уровень культуры разработки у вас выше чем у 90% столичных контор. Да и ребята на порядок сильнее.
  • Инкапсуляция интерфейсов. Делаем API в C++ удобным и понятным
    0
    Есть такой же typedef для std::string. Мы с Вами оба видим замечательные стеки с кучей ненужной информации во время ошибок компиляции, линковки или логирования через typeid: std::basic_string<… std::allocator <… > > и т.д. Особенно если мы специализируем шаблон от std::string, там вообще песня получается. Если перегрузка от std::string, или конструкции, содержащей подобный typedef, тоже получаем километровую неинформативную простыню. Вам это точно надо? Вы хотите множить подобный подход? Одно дело через using отсекать лишние упоминания namespace'ов — пространства имён как раз благо, а совсем другое — создавать видимость, что всё хорошо, когда всё крайне запущено, запутано и переусложнено.
    API обязан быть простым, понятным и в нём не должно быть ничего лишнего. Sine qua non.
    Разработчик, использующий Ваш API не должен через раз делать dynamic_cast, static_cast или, не дай бог, const_cast, только потому, что разработчик API не предусмотрел очевидные use cases. Всё должно быть логично и максимально минималистично в использовании.
  • Инкапсуляция интерфейсов. Делаем API в C++ удобным и понятным
    0
    В object::data конечно же нужен виртуальный деструктор. Вечером всё поправлю. Извините за неточность. Вообще shared_ptr тоже не вариант, больше подойдет комбинация подходов из первых двух статей: by-value или copy-on-write — оптимально и без дополнительных затрат.
  • Инкапсуляция интерфейсов. Делаем API в C++ удобным и понятным
    0
    Объект на куче прекрасно оптимизируется, во-первых by-value из материала второй статьи через placement new для небольших объектов, во-вторых через copy-on-write для больших объектов. Двойная логика работы с классами в больших проектах всё равно пишется, если используется Pimpl, здесь подход позволяет осмыслить классы данных, спрятанные в реализации, через аналогичное дерево иерархии. Зачем: мы пишем код без указателей и ссылок, работая именно с экземплярами классов, а не с какими-то малопонятными ссылками на то, что создала фабрика и выдала нам в виде неудобной синтаксической конструкции в лучшем случае или в виде raw указателя в худшем.
    Если вы инкапсулируете привычные интерфейсы типа ISomething* в удобные классы работы с этими интерфейсами Something, то это хорошо. Если вам платят за то, что вы просто пишете код, который хоть как-то работает, не расширяем и трудно читаем — это тоже неплохо (но не для новичка разбирающего ваш код, конечно же).
  • Python 3.5; async/await
    +1
    Хорошая статья и хороший подход с async/await. Python как всегда всё больше радует с каждой версией.
  • Инкапсуляция интерфейсов. Делаем API в C++ удобным и понятным
    0
    Чтобы было ближе к Qt имеет смысл сделать copy-on-write для данных. То есть заменить на небольшую обвязку наз std::shared_ptr с перегрузкой operator -> с const. Вообще действительно похоже.
  • Инкапсуляция интерфейсов. Делаем API в C++ удобным и понятным
    0
    Спасибо, посмотрю.
  • Инкапсуляция интерфейсов. Делаем API в C++ удобным и понятным
    0
    То, что это единственная причина, по которой здесь нужен виртуальный деструктор, в такой модели в наследниках нет никаких данных, да и сами деструкторы в них не подразумеваются.
  • Инкапсуляция интерфейсов. Делаем API в C++ удобным и понятным
    0
    Скорость разработки с использованием таких классов прямо пропорциональна скорости разработки приложения. Скорость разработки интерфейсных классов при этом не отличается от разработки из с применением паттерна Pimpl.
    В некоторых случаях у нас нет выбора и часть функционала надо писать на C++, при этом предоставляя удобный интерфейс для работы другим разработчикам.
    Pimpl'ы повзоляют легко менять реализацию. В приведённом коде так же легко можно менять поля и реализацию классов object::data с наследниками. Здесь преимуществ не меньше, а больше. Этот подход гибче и дополнительные классы более обоснованы.
    Связка с другими языками это хорошо, но данный подход будет отлично работать и сам по себе в C++ для C++, предоставляя удобный способ работы с иерархией классов.
  • Инкапсуляция интерфейсов. Делаем API в C++ удобным и понятным
    +1
    Всё на самом деле гораздо интереснее. Сейчас C++ очень часто встраивается в высокоуровневые библиотеки бизнес-логики и писать биндинги под такие обобщённые объекты на порядок проще. Соответственно преобразования в те же Python и C# получаются крайне простыми и код будет почти одинаковым, что важно. Это верно и в обратную сторону, в игровой индустрии например C++ состовляет основу движка и поверх идёт скриптовая обвязка, оптимизировать данный подход несложно, а разработчики будут легко работать как внутри движка, так и в расширениях. Сейчас скорость разработки на вес золота.
    Кроме всего прочего очень часто библиотеки общего пользования очень часто изобилуют Pimpl'ами. Данный подход позволяет оптимизировать расходы на разработку «классов реализации» выстроив иерархию классов данных, что опять же положительно скажется на скорости разработки.
    Не стоит также забывать на скорость вхождения в работу новых людей. Код получается простым и понятным, в нём проще разобраться, новички быстро втягиваются и пишут полноценный код. Опять же увеличивая скорость разработки.
  • Инкапсуляция интерфейсов. Делаем API в C++ удобным и понятным
    0
    Вы правы, всё что нужно — это добавить конструктор перемещения object(object&&) и оператор перемещения operator = (object&&). В целом можно вообще разделить объекты по ссылке и по значению как из второй статьи цикла Академии с оптимизацией placement new для небольших классов и скаляров. Также можно внутри класса в принципе запретить null-значения, то есть ругаться на object без данных и на dynamic_cast, который вернул null. В целом идею можно развивать до полноценной библиотеки или встраивать в существующую, профит весьма привлекателен.
  • Всё, точка, приплыли! Учимся работать с числами с плавающей точкой и разрабатываем альтернативу с фиксированной точностью десятичной дроби
    0
    Чтобы не получилось рисование совы, нужно просто читать по порядку, включая предыдущий параграф.
  • Побег из темницы типов. Реализуем работу с данными, тип которых определяется динамически
    0
    Тоже вариант, но так нагляднее, не приходится везде во всех методах писать проверку на nullptr для m_data. Впрочем никто не запрещает создать шаблон от типа данных, наподобие nullable<typename data_type> и перегрузить там operator -> для проверки на nullptr указателя на data_type. Но опять же, теряется наглядность учебного материала.
  • Побег из темницы типов. Реализуем работу с данными, тип которых определяется динамически
    0
    Ну сам-то object с данными по умолчанию вполне себе всегда is_null(), а вот его наследники null далеко не всегда.
  • Как продеть слона через игольное ушко. Обработка максимальных объемов данных за минимальное время
    0
    Не стоит забывать о том, что мапа всё-таки сортирована по ключам. Иногда это важно.
  • Как продеть слона через игольное ушко. Обработка максимальных объемов данных за минимальное время
    0
    Ну и чего обижаться-то? Как можно сравнивать листинг IL-кода против нативных инструкций скомпилированного и оптимизированного кода на C/C++? Каким бы шустрым CLR ни был, это всё равно лишняя трансляция в машинные инструкции. Хотите померяться с сишником скоростью выполнения managed кода против нативного. Весьма похвально стремление, с каким отстаивается точка зрения и любимые технологии, но это малость опрометчиво. Сериализацию вообще на C# или Java писать не очень эффективно, но если есть пример, где прямо по бенчмаркам C# библиотека уделывает все сишные, я бы на это посмотрел.
  • Как продеть слона через игольное ушко. Обработка максимальных объемов данных за минимальное время
    0
    Я знаю C# достаточно хорошо, как и .NET Framework в целом и CLR в частности, я говорю лишь о том, что unsafe конструкции не являются нормальной практикой языка и их использование всегда несёт некоторые ограничения, не говоря уже об обёртках из namespace Marshal. Их применение сродни ассемблерной вставке и в этом случае я предпочитаю написать честный нативный модуль и работать с памятью из C/C++, а уж точно не из C#, который в этом случае использовать неэффективно иначе, кроме как для вызова кода обёрток методов.
  • Грустная история забытых символов. Как не сойти с ума при работе с кодировками в C++
    0
    Не всё так просто, это в простейшем случае regex банально ищет подстроку в строке, чаще требуется находить группы или множества символов, производить замену групп и множеств в различных комбинациях. Regex логически работает с символами, а не с цепочками байт в строке.
  • Грустная история забытых символов. Как не сойти с ума при работе с кодировками в C++
    0
    Массив индексов будет перестраиваться каждый раз, когда будет применяться операция замены по регулярному выражению. По сути может перестроиться вся строка, а фактически и весь набор твоих элементов. Либо ограничиваешься константностью представленного строкового объекта, вынуждая разработчика автоматически и безконтрольно создавать совершенно ненужные промежуточные мини-объекты строк, как это сделано, например, в Python. Если же у тебя два массива дублируют друг друга, возникает также проблема консистентности двух представлений одних и тех же данных.
  • Грустная история забытых символов. Как не сойти с ума при работе с кодировками в C++
    0
    Чтобы искать подстроку одной строки аналогичную строковому паттерну, нужно на каждой итерации склеивать из байтов код символа, обходя заранее неизвестное количество элементов. Куда проще находить соответствие между кодами символов в строках.
  • Как продеть слона через игольное ушко. Обработка максимальных объемов данных за минимальное время
    0
    Как я уже написал выше, unsafe блок крайне ограниченная по своему применению структура языка C#, что именно там можно, а что нельзя. Можно также вспомнить про Marshal и IntPtr, но это вообще доступ к коду, фактически написанному на C/C++ и больше подходит для обёртки, чем для полноценной работы.