Библиотека C/C++ разработчика | cpp, boost, qt
23.2K subscribers
2.17K photos
67 videos
16 files
4.51K links
Все самое полезное для плюсовика и сишника в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/d6cd2932

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a5bac324c8ba6dcaa1ad17

#WXSSA
Download Telegram
📰 Свеженькое из мира C++

Подготовили подборку самых интересных материалов за неделю о разных аспектах программирования и интересных проектах в мире C++.

😎 Интересное:

Как уволиться грамотно: 8 шагов, чтобы закрыть все вопросы — разбираемся как подготовиться к увольнению
constexpr аллокации в C++20: new при компиляции — разбираемся почему теперь можно аллоцировать память во время компиляции
Бесплатная база по C++ с тонной практики — бесплатный курс по C++
8 признаков, что тебя готовят к увольнению — будь осторожен, эти признаки тебе намекнут на то, что тебе нужно вспоминать свой пароль от HH

📙 Ranges:

Алгоритмы диапазонов: Алгоритмы поиска
Алгоритмы диапазонов: Алгоритмы сортировки

🔹📍Навигация: ВакансииЗадачиСобесы

Библиотека C/C++ разработчика

#свежак
😁3
🍪 Как выдать shared_ptr на себя из метода?

std::shared_ptr
хранит рядом с объектом control block — счётчик владельцев. Несколько shared_ptr безопасны, пока делят один control block. Проблема: иногда объекту нужно отдать shared_ptr на себя, но внутри метода есть только сырой this, который о counter'е ничего не знает.


Наивный способ:

struct S {
std::shared_ptr<S> self() { return std::shared_ptr<S>(this); }
};
auto p = std::make_shared<S>();
auto q = p->self();


У p и q свои control block'и, у каждого счётчик = 1 → объект удалится дважды (UB).


Решение — enable_shared_from_this:

struct S : std::enable_shared_from_this<S> {
std::shared_ptr<S> self() { return shared_from_this(); }
};
auto p = std::make_shared<S>();
auto q = p->self();


База добавляет скрытый weak_ptr<S>. При первом заворачивании в shared_ptr его конструктор замечает эту базу и кладёт туда свой control block. Теперь q разделяет счётчик с p.


🍴 Что делает shared_from_this():

shared_ptr<S> shared_from_this() { return shared_ptr<S>(weak_this); }


Это конструктор из weak_ptr, а не lock(): без владельца он бросает bad_weak_ptr, а не молча возвращает пустой указатель.


🍙 Когда скрытый weak_ptr пуст:

S s;                            // на стеке — никто не владеет
s.shared_from_this(); // 💥 bad_weak_ptr (до C++17 — UB)

struct T : std::enable_shared_from_this<T> {
T() { shared_from_this(); } // 💥 хук срабатывает после конструктора
};


Правила: наследовать публично, владеть через shared_ptr (лучше make_shared). Нужна проверка без исключения — в C++17 есть weak_from_this():


🍉 Правила:

• Наследуйте enable_shared_from_this публично.
• Владейте объектом через shared_ptr — лучше make_shared (одна аллокация + exception-safety).
• Не вызывайте shared_from_this() в конструкторе и на объектах со стека — будет bad_weak_ptr.
• Нужна проверка без исключения — в C++17 берите weak_from_this():
if (auto sp = obj.weak_from_this().lock()) { /* владелец есть */ }



📍Навигация: ВакансииЗадачиСобесыКанал в Max

Библиотека C/C++ разработчика

#под_капотом
Please open Telegram to view this post
VIEW IN TELEGRAM
🥰4🔥31👍1
🐾 Алгоритмы диапазонов: Алгоритмы модификации

Разберём copy, transform, fill/generate, а также remove, reverse и unique — и заодно увидим, почему «удаление» в C++ удаляет не сразу.


🍵 ranges::copy / copy_if — копирование

std::vector<int> src = {1, 2, 3, 4, 5};
std::vector<int> dst(5);

std::ranges::copy(src, dst.begin()); // dst == {1, 2, 3, 4, 5}

// Копирование с условием
std::vector<int> evens;
std::ranges::copy_if(src, std::back_inserter(evens),
[](int x) { return x % 2 == 0; });
// evens == {2, 4}


Приёмник — один итератор (куда писать). Под copy буфер должен быть нужного размера; для copy_if берут std::back_inserter — он сам расширяет контейнер.

❗️ copy не терпит перекрытия источника и приёмника (UB). Для пересечения — copy_backward.


⬆️ ranges::move / swap_ranges — перемещение и обмен

std::vector<std::string> src = {"alpha", "beta", "gamma"};
std::vector<std::string> dst(3);

// Перемещение вместо копирования
std::ranges::move(src, dst.begin());
// dst == {"alpha", "beta", "gamma"}
// src содержит валидные, но "опустошённые" строки

// Обмен содержимым двух диапазонов
std::vector<int> a = {1, 2, 3};
std::vector<int> b = {4, 5, 6};

std::ranges::swap_ranges(a, b);
// a == {4, 5, 6}, b == {1, 2, 3}


move переносит ресурсы, а не копирует — дёшево для строк, векторов и прочих «тяжёлых» типов.

❗️ После move источник валиден, но содержимое не определено (valid but unspecified). Пустыми строки не гарантированы — только присвоить заново или уничтожить.


🌳 ranges::transform — преобразование

std::vector<int> src = {1, 2, 3, 4, 5};
std::vector<int> squared(5);

std::ranges::transform(src, squared.begin(), [](int x){ return x * x; });
// squared == {1, 4, 9, 16, 25}


Применяет функцию к каждому элементу и пишет результат в приёмник. Источник не меняется.


🍩 ranges::fill / generate — заполнение

std::vector<int> dst(5);

std::ranges::fill(dst, 0); // {0, 0, 0, 0, 0}

std::ranges::generate(dst, [n = 0]() mutable { return n++; });
// {0, 1, 2, 3, 4}


fill кладёт одно и то же значение, generate зовёт функцию на каждый элемент — удобно для счётчиков, случайных чисел или любой генерации «на лету».


🥳 ranges::remove — удаление (erase-remove стал проще)

std::vector<int> data = {1, 2, 3, 2, 4, 2, 5};

// Старый способ:
data.erase(std::remove(data.begin(), data.end(), 2), data.end());

// Новый способ (C++20):
auto [first, last] = std::ranges::remove(data, 2);
data.erase(first, last);
// data == {1, 3, 4, 5}


Важный момент: remove ничего физически не удаляет — он лишь сдвигает «выжившие» элементы в начало и возвращает поддиапазон «мусорного хвоста». Реально обрезает контейнер только последующий erase.

❗️ Если контейнер свой (а не чужой диапазон), ещё короче — свободная функция std::erase(data, 2): одна строка вместо пары.


🍿 ranges::reverse — разворот

std::vector<int> data = {1, 3, 4, 5};
std::ranges::reverse(data); // {5, 4, 3, 1}


Переворачивает диапазон на месте, без дополнительной памяти.


🎵 ranges::unique — удаление соседних дубликатов

std::vector<int> dups = {1, 1, 2, 3, 3, 3, 4};

auto [u_first, u_last] = std::ranges::unique(dups);
dups.erase(u_first, u_last);
// dups == {1, 2, 3, 4}


Как и remove, возвращает поддиапазон хвоста и требует erase для реальной очистки.

❗️ Убирает только соседние повторы — чтобы вычистить все дубликаты, диапазон сначала надо отсортировать.


🍴 Проекции — работают и здесь

struct Task {
std::string name;
int priority;
};

std::vector<Task> tasks = {
{"Код", 1}, {"Почта", 0}, {"Деплой", 2}, {"Черновик", 0}
};

// Удалить все задачи с priority == 0 — без лямбды
auto [first, last] = std::ranges::remove(tasks, 0, &Task::priority);
tasks.erase(first, last);
// Остались {"Код", 1} и {"Деплой", 2}


Проекция — последний аргумент: remove, copy_if, transform и другие умеют работать «по полю».

❗️ Но проекция — не предикат. У remove это лишь сравнение на равенство; для условий сложнее (priority > 0) нужен remove_if.


📍Навигация: ВакансииЗадачиСобесыКанал в Max

Библиотека C/C++ разработчика

#константная_правильность
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
⚡️ Продолжаем знакомить вас с экспертами курса AgentOps!

Сергей Нотевский расскажет, как выстроить FinOps для AI-продуктов: оптимизировать затраты на разработку и продакшен, внедрить model routing, semantic cache и систему алертов для контроля расходов
Эмиль Сатаев разберет Context Engineering: управление контекстом, защиту от prompt injection, работу с длинными контекстами и построение безопасного пайплайна входа для AI-систем
Михаил Бондаревский покажет, как подготовить инфраструктуру для AI-агентов: Docker, sandboxing, streaming, docker-compose и воспроизводимое окружение для разработки и продакшена
Мурат Хажгериев расскажет про Enterprise Integrations & MCP: когда MCP действительно нужен, как подключать внешние сервисы и реализовывать интеграции с OAuth2 delegation
Герман Сабиров разберет Governance & Compliance для AI-систем: data flow, audit logs, требования 152-ФЗ, локализацию данных и построение compliance-подхода на уровне архитектуры

Курс для backend-разработчиков, тимлидов и LLM инженеров о том, как внедрять AI-логику в бэкенд IT-продуктов и сохранять стабильность сервиса.

👉 Изучить обновленную программу AgentOps и занять место.