Собираем простой пул объектов на C++!
Иногда объект дорого создавать заново каждый раз. Например, буфер, парсер, контекст или структура с заранее выделенной памятью.
В этой задаче:
Такой подход помогает снизить количество аллокаций и делает повторное использование ресурсов более явным.
📣 C++ Ready | #задача
Иногда объект дорого создавать заново каждый раз. Например, буфер, парсер, контекст или структура с заранее выделенной памятью.
В этой задаче:
• храним свободные объекты
• выдаём готовый экземпляр
• возвращаем объект обратно
• очищаем состояние перед повторным использованием
Такой подход помогает снизить количество аллокаций и делает повторное использование ресурсов более явным.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤3🔥1😁1
Почему setprecision не всегда означает количество знаков после точки?
В C++ для форматирования дробных чисел часто используют std::setprecision. На первый взгляд кажется, что он задаёт количество цифр после запятой.
Но без std::fixed это не так:
Результат будет не 123.456 с тремя знаками после точки. Поток выведет три значащие цифры:
Если нужны знаки после точки, добавляют std::fixed:
Теперь результат будет предсказуемым:
Для маленьких чисел разница ещё заметнее:
Без fixed поток снова считает значащие цифры и может перейти к компактной форме вывода.
std::setprecision сам по себе управляет точностью, а не обязательно количеством символов после точки.
📣 C++ Ready | #совет
В C++ для форматирования дробных чисел часто используют std::setprecision. На первый взгляд кажется, что он задаёт количество цифр после запятой.
Но без std::fixed это не так:
std::cout << std::setprecision(3) << 123.456;
Результат будет не 123.456 с тремя знаками после точки. Поток выведет три значащие цифры:
123
Если нужны знаки после точки, добавляют std::fixed:
std::cout << std::fixed << std::setprecision(3)
<< 123.456;
Теперь результат будет предсказуемым:
123.456
Для маленьких чисел разница ещё заметнее:
std::cout << std::setprecision(2) << 0.012345;
Без fixed поток снова считает значащие цифры и может перейти к компактной форме вывода.
std::setprecision сам по себе управляет точностью, а не обязательно количеством символов после точки.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍6🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
Обучение идёт от работы с памятью, классов и наследования до шаблонов, STL, RAII, умных указателей и других возможностях C++. Теория закрепляется на учебном проекте, а ещё есть лабораторные, экзаменационные материалы и отдельный демо-проект с юнит-тестами, паттернами и архитектурой MVP.
Оставляю ссылочку: GitHub📱
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍7🔥4
Почему std::move сам ничего не перемещает?
Кажется, что вызов уже перенёс данные из одного объекта в другой.
На деле std::move только сообщает компилятору, что объект можно рассматривать как временный. Само перемещение происходит, когда другой код выбирает move-конструктор или move-присваивание.
Здесь строка target забирает ресурсы source. После этого source остаётся валидной, но её содержимое не определено контрактом и часто оказывается пустым.
Поэтому нельзя писать логику, которая рассчитывает на конкретное значение после перемещения.
У std::move есть ещё одна ловушка. Перемещение из const-объекта обычно превращается в копирование, потому что move-конструктор не может менять источник.
Такой код компилируется, но для std::string будет создана копия. Полезно применять std::move на последнем использовании объекта, когда прежнее значение действительно больше не нужно.
📣 C++ Ready | #совет
Кажется, что вызов уже перенёс данные из одного объекта в другой.
На деле std::move только сообщает компилятору, что объект можно рассматривать как временный. Само перемещение происходит, когда другой код выбирает move-конструктор или move-присваивание.
std::string source = "report";
std::string target = std::move(source);
Здесь строка target забирает ресурсы source. После этого source остаётся валидной, но её содержимое не определено контрактом и часто оказывается пустым.
Поэтому нельзя писать логику, которая рассчитывает на конкретное значение после перемещения.
send(std::move(message));
// message больше не используем как прежнее значение
У std::move есть ещё одна ловушка. Перемещение из const-объекта обычно превращается в копирование, потому что move-конструктор не может менять источник.
const std::string name = "ready";
auto copy = std::move(name);
Такой код компилируется, но для std::string будет создана копия. Полезно применять std::move на последнем использовании объекта, когда прежнее значение действительно больше не нужно.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤6🔥3
Большой разбор C++ механик!
Автор собрал масштабный материал по приёмам, которые встречаются в современном и легаси C++ коде. Внутри есть RAII, Scope Guard, умные указатели, move-семантика, шаблоны, исключения, Pimpl и десятки других идей с объяснением, откуда они появились.
В статье разбирают:
• как связывать владение ресурсом со временем жизни объекта
• почему noexcept влияет на производительность контейнеров
• где старые идиомы помогают понять код движков и библиотек
📣 C++ Ready | #статья
Автор собрал масштабный материал по приёмам, которые встречаются в современном и легаси C++ коде. Внутри есть RAII, Scope Guard, умные указатели, move-семантика, шаблоны, исключения, Pimpl и десятки других идей с объяснением, откуда они появились.
В статье разбирают:
• как связывать владение ресурсом со временем жизни объекта
• почему noexcept влияет на производительность контейнеров
• где старые идиомы помогают понять код движков и библиотек
Продолжай читать на Habr
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍6🔥3
Почему std::move иногда вообще ничего не двигает?
std::move не перемещает объект сам по себе. Он только превращает выражение в rvalue-ссылку, чтобы компилятор мог выбрать move-конструктор или move-присваивание.
Но если объект const, перемещение может неожиданно превратиться в обычное копирование:
Кажется, что здесь будет move.
Но move-конструктор строки обычно принимает неконстантную rvalue-ссылку:
А из const объекта нельзя безопасно “забрать” внутреннее состояние, потому что это изменило бы объект.
Поэтому компилятор выбирает копирование:
Нормальное перемещение работает с неконстантным объектом:
После такого name остаётся валидным, но его содержимое уже не стоит использовать как прежнее значение:
std::move не гарантирует перемещение. Если объект const, чаще всего ты получишь копирование, просто записанное очень уверенным синтаксисом.
📣 C++ Ready | #совет
std::move не перемещает объект сам по себе. Он только превращает выражение в rvalue-ссылку, чтобы компилятор мог выбрать move-конструктор или move-присваивание.
Но если объект const, перемещение может неожиданно превратиться в обычное копирование:
const std::string name = "ready";
std::string copy = std::move(name);
Кажется, что здесь будет move.
Но move-конструктор строки обычно принимает неконстантную rvalue-ссылку:
std::string(std::string&& other);
А из const объекта нельзя безопасно “забрать” внутреннее состояние, потому что это изменило бы объект.
Поэтому компилятор выбирает копирование:
const std::string name = "ready";
std::string result = std::move(name); // copy
Нормальное перемещение работает с неконстантным объектом:
std::string name = "ready";
std::string result = std::move(name); // move
После такого name остаётся валидным, но его содержимое уже не стоит использовать как прежнее значение:
std::cout << result << '\n';
std::move не гарантирует перемещение. Если объект const, чаще всего ты получишь копирование, просто записанное очень уверенным синтаксисом.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍5🔥3
Шпаргалка по форматированию через библиотеку fmt!
На картинке собраны плейсхолдеры, именованные аргументы, выравнивание, ширина поля, точность, форматы чисел, строк, указателей и диапазонов.
Например, fmt::format собирает строку по шаблону, fmt::print выводит её сразу в консоль, а fmt::format_to пишет результат в готовый буфер или итератор.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
На картинке собраны плейсхолдеры, именованные аргументы, выравнивание, ширина поля, точность, форматы чисел, строк, указателей и диапазонов.
Например, fmt::format собирает строку по шаблону, fmt::print выводит её сразу в консоль, а fmt::format_to пишет результат в готовый буфер или итератор.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤5🔥2
Сравниваем два списка файлов на C++!
Допустим, есть ожидаемый список файлов релиза и список того, что реально попало в папку. Нужно быстро понять, какие файлы отсутствуют, не проходя вручную по каждому имени.
Для этого удобно использовать std::ranges::set_difference. Алгоритм работает с отсортированными диапазонами и сразу возвращает элементы, которые есть в первом списке, но отсутствуют во втором.
Сначала приводим оба списка к одному порядку. Это важно, потому что set_difference не сортирует данные самостоятельно.
Теперь создаём контейнер для результата и передаём в него элементы, которые не нашлись во втором диапазоне.
В missing останется только config. Так же можно искать лишние файлы, поменяв expected и actual местами.
Этот приём подходит для проверки состава релиза, конфигураций, прав доступа и любых двух наборов строк. Главное помнить про сортировку и не хранить дубликаты там, где они не имеют смысла.
📣 C++ Ready | #практика
Допустим, есть ожидаемый список файлов релиза и список того, что реально попало в папку. Нужно быстро понять, какие файлы отсутствуют, не проходя вручную по каждому имени.
Для этого удобно использовать std::ranges::set_difference. Алгоритм работает с отсортированными диапазонами и сразу возвращает элементы, которые есть в первом списке, но отсутствуют во втором.
std::vector<std::string> expected = {"app", "config", "readme"};
std::vector<std::string> actual = {"app", "readme"};Сначала приводим оба списка к одному порядку. Это важно, потому что set_difference не сортирует данные самостоятельно.
std::ranges::sort(expected);
std::ranges::sort(actual);
Теперь создаём контейнер для результата и передаём в него элементы, которые не нашлись во втором диапазоне.
std::vector<std::string> missing;
std::ranges::set_difference(expected, actual,
std::back_inserter(missing));
В missing останется только config. Так же можно искать лишние файлы, поменяв expected и actual местами.
for (const auto& name : missing) {
std::cout << "Missing: " << name << '\n';
}Этот приём подходит для проверки состава релиза, конфигураций, прав доступа и любых двух наборов строк. Главное помнить про сортировку и не хранить дубликаты там, где они не имеют смысла.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍5🔥2
Считаем медиану потока чисел на C++!
Представьте, что значения приходят постоянно, а медиану нужно знать после каждого нового числа. Полная сортировка на каждом шаге будет лишней.
В этой задаче:
Решение подходит для поступающих в реальном времени измерений, цен и задержек.
📣 C++ Ready | #задача
Представьте, что значения приходят постоянно, а медиану нужно знать после каждого нового числа. Полная сортировка на каждом шаге будет лишней.
В этой задаче:
• делим числа на две кучи
• поддерживаем размеры половин
• берём медиану из верхушек куч
Решение подходит для поступающих в реальном времени измерений, цен и задержек.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🔥7👍5😁1
Визуализируем сортировку с SFML и C++20!
QuickSort проще понять, когда видно, как массив делится на части и элементы меняются местами. Автор берёт случайные числа, рисует их столбцами в окне SFML и связывает сортировку с обновлением изображения.
В статье разбирают:
• как подготовить массив и окно для визуализации
• как работает разбиение вокруг опорного элемента
• где рекурсия сортирует левую и правую части
📣 C++ Ready | #статья
QuickSort проще понять, когда видно, как массив делится на части и элементы меняются местами. Автор берёт случайные числа, рисует их столбцами в окне SFML и связывает сортировку с обновлением изображения.
В статье разбирают:
• как подготовить массив и окно для визуализации
• как работает разбиение вокруг опорного элемента
• где рекурсия сортирует левую и правую части
Продолжай читать на Habr
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤6👎2🔥2
Шпаргалка по ассоциативным контейнерам C++!
На картинке сравниваются set, map, unordered_set и unordered_map. Схемы показывают, где хранятся только ключи, где пары ключ-значение и чем упорядоченное дерево отличается от хеш-таблицы.
Например, map подходит, когда нужно обходить ключи по порядку, а unordered_map удобен для поиска без требования к порядку. Рядом есть короткие примеры вставки и доступа к элементам.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
На картинке сравниваются set, map, unordered_set и unordered_map. Схемы показывают, где хранятся только ключи, где пары ключ-значение и чем упорядоченное дерево отличается от хеш-таблицы.
Например, map подходит, когда нужно обходить ключи по порядку, а unordered_map удобен для поиска без требования к порядку. Рядом есть короткие примеры вставки и доступа к элементам.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍5🔥3
Ищем команды по префиксу на C++!
В CLI-приложении пользователь может помнить только начало команды. Сделаем поиск подсказок, который быстро находит подходящие варианты в отсортированном списке.
В этой задаче:
Такой подход пригодится для автодополнения команд и названий настроек.
📣 C++ Ready | #задача
В CLI-приложении пользователь может помнить только начало команды. Сделаем поиск подсказок, который быстро находит подходящие варианты в отсортированном списке.
В этой задаче:
• сортируем команды
• находим начало через lower_bound
• собираем слова с нужным префиксом
Такой подход пригодится для автодополнения команд и названий настроек.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🔥5👍3