Pull to refresh
15
0

Тёмная лошадка

Send message

Напомнило:
Вы неправильно пишете животных https://habr.com/ru/articles/254473/

AnySoftKeyboard довольно хороша, есть кнопки влево-вправо, открытый код, также доступна на F-Droid.


Заголовок спойлера

Тогда все возможные значения [0...4,294,967,295] в противном случае ошибка компиляции. Если же массив на 4 гига не нужен, то необходимо явно делать проверку входных данных на допустимые значения, как показано всё в том же примере чуть ниже.

Видимо проверяет, что все возможные значения i не приводят к выходу за границы массива (тут не важно берётся i из файла, или из чего-то другого). Например если значение i as u8, значит массив должен иметь границы как минимум [0 ..= 255] или больше, в противном случае ошибка компиляции. Подробней: wuffs --> README.md --> What Does Compile Time Checking Look Like?

Вот источник на который ссылается LTT:
2022-10-26 Async Reprojection outside of VR by Comrade Stinger

В описании есть ссылка на билд + исходники (проект на Unity 2021.3.10f1):
* AsyncTimewarp_Movement_Improved.zip
* AsyncTimewarp_UnityProject.zip

Рекоммендую поклацать вживую, на видео не передать все ощущения.
ИМХО этот трюк имеет право на жизнь за пределами VR.
К “новоприобретенным” покупкам M$ не плохо бы наверное ещё добавить GitHub (2018).
В любом случае спасибо за WoG, много хороших воспоминаний. Накопленный опыт, инфа, идеи пошли на пользу геройскому сообществу.
Я лишь пытаюсь донести мысль, что стабильность софта является важным фактором, краши очень сильно портят впечатление о любом проекте. А конкретно в игровом контексте это выбивает игрока из потока, приходится заново запускать/загружать/переигрывать.
Современная HotA и HD mod тоже разрабатываются без исходников оригинала, но результат намного стабильней.
В своё время рубились в третьи герои знатно, в том числе WoG. Имхо всё в этом моде было достаточно хорошо кроме стабильности — частенько в самые неподходящие моменты он полностью крашился, что особенно печалило в режиме «горячего стула».
KDE Kate также хорош, ну а если по хардкору редактор то лучше сразу vim/nvim.
Некоторым по душе VSCodium — это VS Code без телеметрии.
У автора кроме статьи также есть видео на ютубе, там TopoR упоминается на 4:11
www.youtube.com/watch?v=euJgtLcWWyo&t=251s
Маленькие солнечные панели отлично подходят, быстродействие и чувствительность на высоте: habr.com/ru/post/491978
Хороший мини прибор получается в тандеме с любым портативным усилителем.
Не показывает, но отлично озвучивает, я приятно удивлён результатом.
habr.com/ru/post/491978
Интересный проект для организации собственной связи:
Meshtastic — радиомодем на основе LoRa-модулей habr.com/ru/post/568394
Процессор съемный (в сокете) или припаян к плате?
Скорее всего второе, но однозначного ответа не нашел, по фото тоже не понятно.
fk01 10.01.2022 в 05:07

Я бы сказал так, что шаблоны — это на самом деле совсем не шаблоны… На самом деле C++ — это несколько отдельных, по меньшей мере три, языка программирования:

1. язык C-препроцессора осуществляющий подстановку на уровне текста — работает даже не во время, а до компиляции;

2. усовершенствованная версия языка C с классами;

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

Результатом работы упомянутого декларативного языка является генерация некой условной, в явном виде не отображаемой программисту, программы для C-с-классами (подробности можно подглядеть на https://cppinsights.io/).

Основными функциями этого воображаемого декларативного языка, как части C++, являются:

  • преобразование типов (неявное, с использованием пользовательских функций преобразования типов, подстановка конструкторов);
  • статическая диспетчеризация, function lookup, зависимая от типов аргументов, поддержка концепции SFINAE;
  • и самое главное, собственно вишенка на торте: шаблоны.

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

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

Важно понимать, что подразумевается под понятием типа. Тип — это не описание того, как данные хранятся в памяти (структура), это пока не важно (это важно будет для компилятора C с классами). Важно что тип может обладать некоторым набором свойств. В частности вложенными типами, вложенными правилами вывода типов и т.д. и т.п. И на самом деле в пространстве типов попросту возможно программирование, вся программа может целиком исполняться в процессе компиляции, а не после компиляции. Конечно программирование в таком виде не слишком удобно и не предназначено для решения прикладных задач, а предназначено для задач метапрограммирования.

На самом деле конечно описанный декларативный язык не совсем декларативный. Некоторые вещи, например Argument Dependent Lookup начинает зависеть от порядка и видимости деклараций, раскрытие шаблонов тоже. В частности существует такая штука как type loophole которая попросту паразитирует на том факте, что порядок деклараций в C++ всё же имеет значение…

Возвращаясь к шаблонам. Шаблоны названы так исторически. Технически шаблон это совершенно не подстановка текста. Подстановка текста — это C-препроцессор, из чего изначально шаблоны родились. Шаблоны — это именно набор деклараций, используя которые компилятор самостоятельно ищет решение. И в вашей статье описывается, мол есть шаблоны классов, шаблоны функций, шаблоны переменных наконец (начиная с C++14). Но это всё на самом деле не слишком принципиально. Это скорей историческое наследие: типичный пример использования шаблона функций сейчас в метапрограммировании — это отнюдь не генерация функции, а использование автоматического вывода типов. Даже без тела собственно самой функции. Чтоб в шаблоне функции попросту получить типы в виде параметров шаблона (их компилятор автоматически выведет) и использовать их где-то дальше, например для параметризации уже другого шаблона класса. Да, шаблоны можно использовать и для генерации классов, и для генерации функций и переменных, но это давно не единственное их предназначение. Основным я бы назвал реализацию приёмов метапрограммирования.

Процитирую некоторые моменты:
В терминах C++ обобщённое описание функции называется шаблоном функции.

Да и нет. В силу возможности специализации для конкретных параметров шаблона, важным отличием шаблонов в C++ от дженериков в C# и других языках является то, что собственно сами специализации могут быть кардинально разными в зависимости от параметров. Т.е. это не просто подстановка типа, Функция просто может делать совсем что-то другое. Или, в случае специализации класса, специализация для конкретного типа, например, может породить что-то совершенно отличное от обощённой специализации. Данная практика широко используется для задач метапрограмирования.

Так же стоит сказать о порождении класса из шаблона. Принципиальным является то, что класс из шаблона появляется в момент его первого использования (фактически, это в каком-то смысле ленивое вычисление в пространстве типов). И потом уже существует до конца работы компилятора. При определённых обстоятельствах факт генерирования нового типа из шаблона («инстанциации» шаблона) может иметь побочные эффекты и их можно обнаружить. И самое важное, типы от которых шаблон зависит тоже будут востребованы в момент генерации типа из шаблона, а не в момент парсинга шаблона компилятором. В момент парсинга компилятор вынужден работать с определениями которые ещё не определены (отсюда и нужда руками выписывать ключевые слова typename и template внутри шаблона, отсюда же и необходимость создания алиасов для типов, которые до генерации типа из шаблона не видны в пространстве имён, например в случае наследования от класса заданного в параметрах шаблона).

Нужно заметить, что концепты сами по себе не является каким-то новым свойством, по сути это такой синтакс-сахар для удобной замены std::enable_if. Ключевым моментом здесь является не концепт, а сама концепция SFINAE реализуемая C++-компилятором и не реализуемая во многих других языках. Как было сказано выше, компилятор ищет решение, возможную подстановку, и может при этом откинуть некорректные варианты без ошибки.

Не рассмотрен такой важный вопрос, что в C++ параметром шаблона может являться другой шаблон. Это тоже принципиальное отличие C++ от других языков с обобщёнными функциями (generics). Шаблон принявший другой шаблон сам может параметризовать его как ему нужно и начать использовать полученные из этого шаблона функции и типы. Без такого функционала, метапрограммирование в C++ было бы очень ограничено.

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

Процитирую ещё:
Макросы выполняют текстовую подстановку аргументов, в то время как шаблоны лексически и синтаксически проверяются компилятором

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

Затрудняют ли шаблоны отладку кода?

Пошаговая отладка, например в gdb, или в VisualStudio, сколько-нибудь сложного кода с шаблонами скорей не реальна. Отладчик конечно будет отлично шагать по сгенерированным из шаблона функциям, проблема не в этом. Проблема в том, чтоб шаблонный код управляет работой компилятора, и сгенерировано в итоге может быть что-то совсем не то, на что расчитывал программист. Ошибка может быть такая, что её при пошаговой отладке просто будет невозможно понять. Потому, что шаблоны — это процесс компиляции, а не исполнения.

Если нужно отладить шаблоны, то как правило есть две проблемы:

1. ошибка компиляции — для gcc или clang сейчас вывод компилятора достаточно хорош, показывается весь путь раскрытия шаблонов, параметры шаблонов. Ситуация реально лучше, чем было лет 10 тому назад. Компиляторы не полностью разворачивают всю историю, и если не хватает вывода, то можно использовать опцию -ftemplate-backtrace-limit.

2. непонятно что вообще получается, ошибки допустим нет. В такой ситуации можно использовать metashell для того, чтобы понять во что превращаются шаблоны. Впрочем часто достаточно спровоцировать ошибку и посмотреть вывод компилятора…

PS: в статье на мой взгляд слишком длинные и нудные примеры, что затрудняет понимание новичками. Примеры по-моему лучше сделать короткими, и заодно помимо исторических использований шаблонов показать основные ключевые приёмы метапрограммирования. Например такие как std::void_t, std::integer_sequence, std::enable_if и ключевое слово decltype (чего так же нет во многих других других языках, а в C существует в виде нестандартного typeof), std::declval (который в голом C спрятан в макросе offsetof), можно показать, как шаблоны могут использоваться для вывода возвращаемого значения и типов аргументов другой функции и тому подобные вещи…
Я не в курсе чем провинился этот пользователь, но видимо если аккаунт был деактивирован/удалён, то все комменты тоже исчезают.
Вот ссылка для тех, кто как и я захочет почитать отличный коммент fk01 который утащило НЛО.
Слабоватая статейка, мало что можно оценить по таким данным.
1
23 ...

Information

Rating
3,588-th
Registered
Activity