std::string_view не владеет строкой и в этом легко ошибиться!
Поэтому такой код опасен:
Если
Безопасный вариант сначала сохранить строку:
Теперь
Такой метод принимает строковые литералы,
А вот возвращать представление локальной строки нельзя:
После выхода из функции
📣 C++ Ready | #совет
std::string_view хранит только указатель на символы и их количество. Он не копирует текст и не продлевает время жизни исходной строки.Поэтому такой код опасен:
std::string_view name = make_name();
Если
make_name() возвращает std::string, временная строка уничтожается в конце выражения. После этого name продолжает указывать на уже недействительную память.Безопасный вариант сначала сохранить строку:
std::string name = make_name();
std::string_view view = name;
Теперь
view можно использовать, пока существует name и операции со строкой не сделали указатель недействительным.string_view хорошо подходит для параметров функций, которые только читают текст:void print_name(std::string_view name) {
std::cout << name << '\n';
}Такой метод принимает строковые литералы,
std::string и другие непрерывные последовательности символов без лишнего копирования:std::string user = "Alex";
print_name(user);
print_name("Admin");
А вот возвращать представление локальной строки нельзя:
std::string_view get_status() {
std::string status = "ready";
return status;
}После выхода из функции
status уничтожается, а возвращённый string_view становится висячим.Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7❤5👍3
Интересный практический проект, собственная игра на C++ для портативной ретроконсоли!
В этой статье:
• Как организовать структуру небольшого игрового проекта
• Как устроить главный игровой цикл и переключение состояний
• Как разделить стартовый экран, игровой процесс и завершение игры
• Как собрать клон Google Dino и запустить его на реальном устройстве
Хороший способ посмотреть, как обычные классы, состояния и игровой цикл превращаются в законченную работающую игру.
📣 C++ Ready | #статья
В этой статье:
• Как организовать структуру небольшого игрового проекта
• Как устроить главный игровой цикл и переключение состояний
• Как разделить стартовый экран, игровой процесс и завершение игры
• Как собрать клон Google Dino и запустить его на реальном устройстве
Хороший способ посмотреть, как обычные классы, состояния и игровой цикл превращаются в законченную работающую игру.
Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👍6🔥3
Как безопасно удалять элементы из контейнера в C++20?
Частая ошибка удалять элементы прямо внутри range-for:
Проблема в том, что обход и изменение контейнера легко приводят к пропуску элементов, инвалидированным итераторам или слишком шумному коду.
В C++20 для этого есть std::erase_if:
После этого в vector останутся только нужные значения:
То же самое удобно работает и с ассоциативными контейнерами:
Здесь удалятся записи, где значение равно нулю, а код останется коротким и читаемым.
📣 C++ Ready | #совет
Частая ошибка удалять элементы прямо внутри range-for:
for (int x : values) {
if (x < 0) {
// удалить x?
}
}Проблема в том, что обход и изменение контейнера легко приводят к пропуску элементов, инвалидированным итераторам или слишком шумному коду.
В C++20 для этого есть std::erase_if:
std::vector<int> values{5, -1, 7, -3};
std::erase_if(values, [](int x) {
return x < 0;
});После этого в vector останутся только нужные значения:
// values: 5, 7
То же самое удобно работает и с ассоциативными контейнерами:
std::map<std::string, int> scores{
{"ann", 10},
{"bob", 0},
{"kim", 7}
};
std::erase_if(scores, [](const auto& item) {
return item.second == 0;
});Здесь удалятся записи, где значение равно нулю, а код останется коротким и читаемым.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥5👍3
Очень интересная статья о том, как автор пытался воссоздать Minecraft на C++ и Vulkan за одну неделю!
В этой статье:
• Как устроена идея voxel-мира и генерации чанков
• Почему Vulkan требует аккуратной работы с рендерингом и ресурсами
• Как маленький прототип постепенно превращается в собственный игровой движок
📣 C++ Ready | #статья
В этой статье:
• Как устроена идея voxel-мира и генерации чанков
• Почему Vulkan требует аккуратной работы с рендерингом и ресурсами
• Как маленький прототип постепенно превращается в собственный игровой движок
Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🔥7👍5
Напоминалка по алгоритмам стандартной библиотеки C++!
Например, std::find_if помогает найти элемент по условию, std::sort сортирует диапазон, а std::transform удобно применять для преобразования значений без ручного цикла.
На картинке шпаргалка по STL-алгоритмам: поиск, сравнение диапазонов, сортировка, partition, rotate, copy, transform, remove, unique и числовые алгоритмы из <numeric>.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
Например, std::find_if помогает найти элемент по условию, std::sort сортирует диапазон, а std::transform удобно применять для преобразования значений без ручного цикла.
На картинке шпаргалка по STL-алгоритмам: поиск, сравнение диапазонов, сортировка, partition, rotate, copy, transform, remove, unique и числовые алгоритмы из <numeric>.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤6👍4
Опа, тут бывший сеньор одного из IT-отделов Яндекса Игорь Никитин выкатил целый канал про Python — и это лучшее, что есть в рунете по теме.
Качественные гайды. Советы от известных прогеров. Тематические мемасы. Короче, ничего лишнего.
Хватит душить питона, учись его кодить: https://t.me/+IzIPzvoa7p40ZTUy 🐍
Качественные гайды. Советы от известных прогеров. Тематические мемасы. Короче, ничего лишнего.
Хватит душить питона, учись его кодить: https://t.me/+IzIPzvoa7p40ZTUy 🐍
👎9👍1
Собираем маленький scope guard!
Иногда нужно выполнить действие при выходе из функции: закрыть временный режим, вернуть флаг обратно, удалить временный файл или откатить локальное состояние.
Писать cleanup руками в каждом return неудобно:
Если return станет больше, легко забыть один из вызовов disable().
Сделаем небольшой scope guard:
В деструкторе он выполнит переданную функцию:
Запретим копирование, чтобы cleanup не вызвался дважды:
Поля класса:
Теперь очистка привязана к области видимости:
disable вызовется и при обычном завершении, и при раннем return.
Тот же подход удобен для временных файлов:
И для восстановления старого значения:
Scope guard это простой способ сделать cleanup надёжным. Код меньше зависит от того, сколько return появится внутри функции.
📣 C++ Ready | #практика
Иногда нужно выполнить действие при выходе из функции: закрыть временный режим, вернуть флаг обратно, удалить временный файл или откатить локальное состояние.
Писать cleanup руками в каждом return неудобно:
void process() {
enable();
if (!check_input()) {
disable();
return;
}
run_job();
disable();
}Если return станет больше, легко забыть один из вызовов disable().
Сделаем небольшой scope guard:
#include <functional>
#include <utility>
class ScopeExit {
public:
explicit ScopeExit(std::function<void()> fn)
: fn_(std::move(fn)) {}
В деструкторе он выполнит переданную функцию:
~ScopeExit() {
if (fn_) {
fn_();
}
}Запретим копирование, чтобы cleanup не вызвался дважды:
ScopeExit(const ScopeExit&) = delete;
ScopeExit& operator=(const ScopeExit&) = delete;
Поля класса:
private:
std::function<void()> fn_;
};
Теперь очистка привязана к области видимости:
void process() {
enable();
ScopeExit guard([] {
disable();
});
if (!check_input()) {
return;
}
run_job();
}disable вызовется и при обычном завершении, и при раннем return.
Тот же подход удобен для временных файлов:
ScopeExit cleanup([&] {
std::filesystem::remove(path);
});И для восстановления старого значения:
bool old = config.debug;
config.debug = true;
ScopeExit restore([&] {
config.debug = old;
});
Scope guard это простой способ сделать cleanup надёжным. Код меньше зависит от того, сколько return появится внутри функции.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍4🔥3
Интересная статья о том, как устроить свою SDL-подобную библиотеку на C++!
В этой статье:
• Как создать окно, renderer и базовый цикл обработки событий
• Как разделять платформозависимый код и общие интерфейсы
• Почему в графических библиотеках важны абстракции, совместимость и управление ресурсами
📣 C++ Ready | #статья
В этой статье:
• Как создать окно, renderer и базовый цикл обработки событий
• Как разделять платформозависимый код и общие интерфейсы
• Почему в графических библиотеках важны абстракции, совместимость и управление ресурсами
Продолжай читать на Habr!
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🔥5👍3
Шпаргалка по special member functions в C++!
Например, если в классе объявить деструктор, компилятор уже не будет автоматически объявлять move constructor и move assignment. А если объявить move constructor, copy-операции могут стать deleted.
На картинке таблица правил генерации специальных методов класса: default constructor, destructor, copy constructor, copy assignment, move constructor и move assignment в зависимости от того, что уже объявил разработчик.
Сохрани, чтобы не потерять!
📣 C++ Ready | #ресурс
Например, если в классе объявить деструктор, компилятор уже не будет автоматически объявлять move constructor и move assignment. А если объявить move constructor, copy-операции могут стать deleted.
На картинке таблица правил генерации специальных методов класса: default constructor, destructor, copy constructor, copy assignment, move constructor и move assignment в зависимости от того, что уже объявил разработчик.
Сохрани, чтобы не потерять!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤5👍5
На Stepik запустили курс по вайбкодингу c Claude Code
Первым делом вы освоите базу Claude Code и научитесь проектировать полноценные приложения.
После этого перейдёте к более продвинутым инструментам и автоматизации:
➡️ Разработаете собственные MCP-серверы и Claude Skills
➡️ Автоматизируете разработку с помощью Agent Loops и хуков
➡️ Освоите Claude Design, Cowork и Connectors
➡️ Построите личную систему знаний на базе Obsidian + Claude Cowork
➡️ Научитесь работать с таблицами при помощи Cowork
➡️ Перестанете постоянно упираться в лимиты Claude
А в финале получите готовую дорожную карту, полезные лайфхаки и 7 практических способов обхода блокировок Claude Code в России.
🔥 В течении 48 часов действует скидка 25%
Первым делом вы освоите базу Claude Code и научитесь проектировать полноценные приложения.
После этого перейдёте к более продвинутым инструментам и автоматизации:
А в финале получите готовую дорожную карту, полезные лайфхаки и 7 практических способов обхода блокировок Claude Code в России.
Please open Telegram to view this post
VIEW IN TELEGRAM
👎12😁3❤1
Собираем типобезопасные флаги через enum class!
Иногда нужно хранить набор прав или режимов: чтение, запись, выполнение, логирование, debug-режимы. Часто для этого используют обычные int-флаги, но с ними легко случайно смешать разные значения.
Начнём с enum class:
Сам по себе enum class не умеет складываться через
Теперь можно собрать набор прав:
Чтобы проверять наличие флага, сделаем маленькую функцию:
Использование получается читаемым:
Можно добавить и удаление флага:
Например, забрать право записи:
Такой подход удобен для прав доступа, настроек движка, режимов логирования, feature flags и любых случаев, где несколько булевых значений логически относятся к одному набору.
📣 C++ Ready | #практика
Иногда нужно хранить набор прав или режимов: чтение, запись, выполнение, логирование, debug-режимы. Часто для этого используют обычные int-флаги, но с ними легко случайно смешать разные значения.
Начнём с enum class:
enum class Permission : unsigned {
Read = 1 << 0,
Write = 1 << 1,
Exec = 1 << 2
};Сам по себе enum class не умеет складываться через
|, поэтому добавим оператор:Permission operator|(Permission a, Permission b) {
return static_cast<Permission>(
static_cast<unsigned>(a) | static_cast<unsigned>(b)
);
}Теперь можно собрать набор прав:
auto user = Permission::Read | Permission::Write;
Чтобы проверять наличие флага, сделаем маленькую функцию:
bool has(Permission value, Permission flag) {
return (
static_cast<unsigned>(value) &
static_cast<unsigned>(flag)
) != 0;
}Использование получается читаемым:
if (has(user, Permission::Write)) {
std::cout << "Можно изменять данные\n";
}Можно добавить и удаление флага:
Permission remove(Permission value, Permission flag) {
return static_cast<Permission>(
static_cast<unsigned>(value) & ~static_cast<unsigned>(flag)
);
}Например, забрать право записи:
user = remove(user, Permission::Write);
Такой подход удобен для прав доступа, настроек движка, режимов логирования, feature flags и любых случаев, где несколько булевых значений логически относятся к одному набору.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍3🔥3