This media is not supported in your browser
VIEW IN TELEGRAM
Этот репозиторий представляет собой подробное руководство по современным практикам разработки на C++. В нём собраны рекомендации по организации проектов, стилю кода, оптимизации производительности, тестированию, работе с инструментами анализа и другим аспектам профессиональной разработки.
Оставляю ссылочку: GitHub
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍8🔥5
Шпаргалка по random distributions в C++!
Например, std::uniform_int_distribution подходит для случайных целых чисел в диапазоне, а std::normal_distribution для значений с нормальным распределением.
На картинке распределения из <random>: uniform, bernoulli, binomial, geometric, normal, lognormal, poisson, exponential, gamma, weibull и другие варианты с формулами и графиками.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
Например, std::uniform_int_distribution подходит для случайных целых чисел в диапазоне, а std::normal_distribution для значений с нормальным распределением.
На картинке распределения из <random>: uniform, bernoulli, binomial, geometric, normal, lognormal, poisson, exponential, gamma, weibull и другие варианты с формулами и графиками.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤11🔥5🤝1
Собираем проверку расширений файлов на C++!
Иногда нужно быстро отфильтровать файлы: взять только
Подключим нужные заголовки:
Функция будет принимать путь и расширение:
Обойдём папку рекурсивно:
Проверим расширение:
Теперь можно найти все JSON-файлы:
Если папки нет,
std::filesystem позволяет писать маленькие файловые утилиты без платформенного кода. Такой фильтр легко расширить под поиск логов, конфигов, бэкапов или временных файлов.
📣 C++ Ready | #практика
Иногда нужно быстро отфильтровать файлы: взять только
.log, .json, .txt или изображения. Сделаем небольшую функцию на std::filesystem, которая проходит по папке и возвращает файлы с нужным расширением.Подключим нужные заголовки:
#include <filesystem>
#include <string>
#include <vector>
namespace fs = std::filesystem;
Функция будет принимать путь и расширение:
std::vector<fs::path> find_files(
const fs::path& root,
std::string_view extension
) {
std::vector<fs::path> result;
Обойдём папку рекурсивно:
for (const auto& entry : fs::recursive_directory_iterator(root)) {
if (!entry.is_regular_file()) {
continue;
}Проверим расширение:
if (entry.path().extension() == extension) {
result.push_back(entry.path());
}
}
return result;
}Теперь можно найти все JSON-файлы:
auto files = find_files("configs", ".json");
for (const auto& file : files) {
std::cout << file << '\n';
}Если папки нет,
recursive_directory_iterator может бросить исключение. Для утилит это нормально обработать явно:try {
auto files = find_files("configs", ".json");
} catch (const fs::filesystem_error& error) {
std::cerr << error.what() << '\n';
}std::filesystem позволяет писать маленькие файловые утилиты без платформенного кода. Такой фильтр легко расширить под поиск логов, конфигов, бэкапов или временных файлов.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍5🔥2
Разберём std::filesystem: 7 операций для работы с файлами и папками в C++!
std::filesystem помогает писать файловые утилиты без платформенного кода: собирать пути, проверять файлы, создавать папки, обходить директории и аккуратно чистить временные данные. Эта шпора пригодится для CLI-инструментов, логов, конфигов, сборочных скриптов и backend-задач на C++.
📣 C++ Ready | #шпора
std::filesystem помогает писать файловые утилиты без платформенного кода: собирать пути, проверять файлы, создавать папки, обходить директории и аккуратно чистить временные данные. Эта шпора пригодится для CLI-инструментов, логов, конфигов, сборочных скриптов и backend-задач на C++.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12❤2👍2
Media is too big
VIEW IN TELEGRAM
hacking C++ визуальный сайт с современными материалами по C++!
На сайте собраны гайды, короткие статьи, рецепты, cheat sheets, инфографика и подборки материалов по современному C++: стандартная библиотека, алгоритмы, ranges, контейнеры, templates, move semantics, memory management, random, diagnostics, best practices и инструменты. Это не одна страница и не сухая документация: можно проваливаться в разделы, листать примеры, открывать инфографику и быстро повторять конкретные темы перед практикой или разбором чужого кода.
📣 C++ Ready | #ресурс
На сайте собраны гайды, короткие статьи, рецепты, cheat sheets, инфографика и подборки материалов по современному C++: стандартная библиотека, алгоритмы, ranges, контейнеры, templates, move semantics, memory management, random, diagnostics, best practices и инструменты. Это не одна страница и не сухая документация: можно проваливаться в разделы, листать примеры, открывать инфографику и быстро повторять конкретные темы перед практикой или разбором чужого кода.
Оставляю ссылочку: hackingcpp.com
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍4🔥3
Зачем в C++ использовать std::optional?
Иногда функция должна показать, что результат может отсутствовать.
Часто для этого возвращают специальное значение:
Проблема в том, что
Код вызова тоже становится неочевидным:
В C++17 для таких случаев есть
Теперь отсутствие результата выражено прямо в типе:
А само значение можно получить после проверки:
Такой подход хорошо подходит для поиска, парсинга, чтения конфига и любых операций, где “ничего не найдено” нормальный сценарий, а не ошибка программы.
📣 C++ Ready | #совет
Иногда функция должна показать, что результат может отсутствовать.
Часто для этого возвращают специальное значение:
int find_user_id(std::string_view name) {
if (name.empty()) {
return -1;
}
return 42;
}Проблема в том, что
-1 это договорённость, которую легко забыть.Код вызова тоже становится неочевидным:
int id = find_user_id(name);
if (id == -1) {
std::cout << "not found\n";
}
В C++17 для таких случаев есть
std::optional:std::optional<int> find_user_id(std::string_view name) {
if (name.empty()) {
return std::nullopt;
}
return 42;
}Теперь отсутствие результата выражено прямо в типе:
auto id = find_user_id(name);
if (!id) {
std::cout << "not found\n";
return;
}
А само значение можно получить после проверки:
std::cout << *id << '\n';
Такой подход хорошо подходит для поиска, парсинга, чтения конфига и любых операций, где “ничего не найдено” нормальный сценарий, а не ошибка программы.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9🔥6👍3
Сильная статья о том, как написать свой компилятор на C++ с использованием LLVM!
В этой статье:
• Как компилятор проходит путь от исходного кода до промежуточного представления
• Зачем нужны лексер, парсер, семантика и LLVM IR
• Как устроить ошибки, типы и генерацию кода в собственном языке
📣 C++ Ready | #статья
В этой статье:
• Как компилятор проходит путь от исходного кода до промежуточного представления
• Зачем нужны лексер, парсер, семантика и LLVM IR
• Как устроить ошибки, типы и генерацию кода в собственном языке
Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤5🔥4
Когда в C++ лучше использовать std::span?
Иногда функция должна работать с массивом, vector или частью данных, но владеть этими данными ей не нужно.
Часто в таком случае передают vector:
Проблема в том, что функция теперь привязана именно к std::vector.
Если у тебя есть обычный массив, придётся писать перегрузку или создавать vector:
В C++20 для таких случаев есть std::span:
Теперь функция принимает разные источники данных:
Можно передать и часть диапазона:
std::span не владеет памятью. Он просто смотрит на уже существующие данные.
Поэтому нельзя возвращать span на локальный массив:
После выхода из функции массив исчезнет, а span останется висячей ссылкой.
📣 C++ Ready | #совет
Иногда функция должна работать с массивом, vector или частью данных, но владеть этими данными ей не нужно.
Часто в таком случае передают vector:
int sum(const std::vector<int>& values) {
int result = 0;
for (int value : values) {
result += value;
}
return result;
}Проблема в том, что функция теперь привязана именно к std::vector.
Если у тебя есть обычный массив, придётся писать перегрузку или создавать vector:
int data[] = {1, 2, 3};
// sum(data) не подойдётВ C++20 для таких случаев есть std::span:
int sum(std::span<const int> values) {
int result = 0;
for (int value : values) {
result += value;
}
return result;
}Теперь функция принимает разные источники данных:
std::vector<int> a{1, 2, 3};
std::array<int, 3> b{4, 5, 6};
int c[] = {7, 8, 9};
sum(a);
sum(b);
sum(c);Можно передать и часть диапазона:
sum(std::span(a).subspan(1, 2));
std::span не владеет памятью. Он просто смотрит на уже существующие данные.
Поэтому нельзя возвращать span на локальный массив:
std::span<int> bad() {
int values[] = {1, 2, 3};
return values;
}После выхода из функции массив исчезнет, а span останется висячей ссылкой.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15❤5🔥4
This media is not supported in your browser
VIEW IN TELEGRAM
Полезный ресурс для разработчиков на C и C++. На сайте собрана подробная документация по языкам и стандартной библиотеке: типы данных, функции, классы, шаблоны, контейнеры, алгоритмы, работа с памятью, потоки, многопоточность и новые возможности стандартов C++11, C++14, C++17, C++20 и C++23.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍8🔥4
Крутая статья про то, как нарисовать мультяшный взрыв на чистом C++ примерно за 180 строк!
В этой статье:
• Как работает ray marching и численное пересечение луча с объектом
• Как добавить освещение, паттерн, displacement mapping и шум
• Как сохранить результат в PPM и получить готовую картинку без графических библиотек
📣 C++ Ready | #статья
В этой статье:
• Как работает ray marching и численное пересечение луча с объектом
• Как добавить освещение, паттерн, displacement mapping и шум
• Как сохранить результат в PPM и получить готовую картинку без графических библиотек
Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍6❤3
Шпаргалка по STL в C++!
Например, vector удобен для быстрого доступа по индексу, set хранит элементы в отсортированном виде, а priority_queue помогает быстро получать максимальный элемент.
На картинке основные контейнеры STL, частые операции, асимптотика, примеры использования sort, binary_search, lower_bound, upper_bound, min_element, max_element, pair, tuple и других полезных инструментов.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
Например, vector удобен для быстрого доступа по индексу, set хранит элементы в отсортированном виде, а priority_queue помогает быстро получать максимальный элемент.
На картинке основные контейнеры STL, частые операции, асимптотика, примеры использования sort, binary_search, lower_bound, upper_bound, min_element, max_element, pair, tuple и других полезных инструментов.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤4🔥4
Собираем небольшой LRU-кэш на C++!
Иногда нужно хранить только последние N значений: результаты дорогих вычислений, ответы локального кэша или недавно использованные настройки. Если лимит превышен, самый старый элемент должен автоматически удаляться.
Для порядка использования удобно взять std::list:
А для быстрого поиска unordered_map:
Добавим лимит:
Когда ключ уже есть, переносим его в начало:
Если ключ новый, просто добавляем его первым:
Теперь проверяем размер кэша:
Соберём это в функцию:
Проверим порядок:
Теперь внутри останутся 4, 1 и 3:
Ожидаемый вывод:
LRU-кэш хорошо показывает, как std::list и unordered_map дополняют друг друга: список хранит порядок, а map даёт быстрый доступ к узлам.
📣 C++ Ready | #практика
Иногда нужно хранить только последние N значений: результаты дорогих вычислений, ответы локального кэша или недавно использованные настройки. Если лимит превышен, самый старый элемент должен автоматически удаляться.
Для порядка использования удобно взять std::list:
std::list<int> order;
А для быстрого поиска unordered_map:
std::unordered_map<int, std::list<int>::iterator> pos;
Добавим лимит:
const std::size_t limit = 3;
Когда ключ уже есть, переносим его в начало:
order.erase(pos[key]);
order.push_front(key);
pos[key] = order.begin();
Если ключ новый, просто добавляем его первым:
order.push_front(key);
pos[key] = order.begin();
Теперь проверяем размер кэша:
if (order.size() > limit) {
pos.erase(order.back());
order.pop_back();
}Соберём это в функцию:
void touch(int key) {
if (pos.contains(key)) {
order.erase(pos[key]);
}
order.push_front(key);
pos[key] = order.begin();
if (order.size() > limit) {
pos.erase(order.back());
order.pop_back();
}
}Проверим порядок:
touch(1);
touch(2);
touch(3);
touch(1);
touch(4);
Теперь внутри останутся 4, 1 и 3:
for (int x : order) {
std::cout << x << ' ';
}Ожидаемый вывод:
4 1 3
LRU-кэш хорошо показывает, как std::list и unordered_map дополняют друг друга: список хранит порядок, а map даёт быстрый доступ к узлам.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7❤4😁2👍1
Делаем простой парсер CLI-флагов на C++!
Нужно быстро разобрать аргументы командной строки без сторонних библиотек? Соберём мини-парсер, который понимает формат --key=value и отдельные boolean-флаги вроде --verbose.
В этой задаче:
Такой подход удобен для утилит и инструментов где не хочется подключать полноценный CLI-фреймворк.
📣 C++ Ready | #задача
Нужно быстро разобрать аргументы командной строки без сторонних библиотек? Соберём мини-парсер, который понимает формат --key=value и отдельные boolean-флаги вроде --verbose.
В этой задаче:
• Храним аргументы в unordered_map;
• Разбираем значения через знак =;
• Поддерживаем флаги без значения.
Такой подход удобен для утилит и инструментов где не хочется подключать полноценный CLI-фреймворк.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍6🔥2😁1