Библиотека C/C++ разработчика | cpp, boost, qt
Все самое полезное для плюсовика и сишника в одном канале. Как запустить своего ии-агента: https://clc.to/tvpmDQ По рекламе: @tproger_sales_bot Обратная связь: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5bac324c8ba6dcaa1ad17 #WXSSA
Больше📈 Аналитический обзор Telegram-канала Библиотека C/C++ разработчика | cpp, boost, qt
Канал Библиотека C/C++ разработчика | cpp, boost, qt (@cppproglib) языкового сегмента Русский является активным участником. Сейчас сообщество объединяет 16 813 подписчиков, занимая 7 717 место в категории Технологии и приложения и 39 129 место в регионе Россия.
📊 Показатели аудитории и динамика
С момента создания невідомо проект демонстрирует стремительный рост, собрав аудиторию из 16 813 подписчиков.
Согласно последним данным от 26 октября, 2026, канал показывает стабильную активность. За последние 30 дней изменение числа участников составило -53, а за последние 24 часа — -12, при этом общий охват остаётся высоким.
- Статус верификации: Не верифицирован
- Уровень вовлечённости (ER): Средний показатель вовлечённости аудитории составляет 10.76%. В первые 24 часа после публикации контент обычно набирает 4.45% реакций от общего числа подписчиков.
- Охват публикаций: В среднем каждый пост получает 1 810 просмотров. В течение первых суток публикация набирает 748 просмотров.
- Реакции и взаимодействия: Аудитория активно поддерживает контент: среднее количество реакций на один пост — 2.
- Тематические интересы: Контент сосредоточен на ключевых темах, таких как c++, навигация, компилятор, удалёнка, developer.
📝 Описание и контентная политика
Автор описывает ресурс как площадку для выражения субъективного мнения:
“Все самое полезное для плюсовика и сишника в одном канале.
Как запустить своего ии-агента: https://clc.to/tvpmDQ
По рекламе: @tproger_sales_bot
Обратная связь: @proglibrary_feeedback_bot
РКН: https://gosuslugi.ru/snet/67a5bac324c8ba6dcaa1ad17
#W...”
Благодаря высокой частоте обновлений (последние данные получены 27 октября, 2026) канал поддерживает актуальность и высокий уровень охвата публикаций. Аналитика показывает, что аудитория активно взаимодействует с контентом, что делает его важной точкой влияния в категории Технологии и приложения.
export. Всё остальное снаружи не видно — но это не «закрытость» уровня файла: у непомеченных сущностей модульное связывание, то есть их видят другие единицы трансляции того же модуля, просто не видит код, который подключает модуль. Это противоположность заголовкам, где в чужой код текстуально попадает вообще всё.
export module geometry;
export struct Point { double x, y; }; // открыто наружу
double dist(Point a, Point b); // скрыто снаружи,
// но доступно внутри модуля
export double length(Point p) { // открыто наружу
return dist(p, {0, 0});
}
Открыть наружу можно почти любую сущность: функции, типы, шаблоны, переменные, псевдонимы using.
🪐 Удобные формы записи
export { // блок экспорта
int foo();
int bar();
}
export namespace net { // только объявления ЭТОГО блока
void connect();
}
export import utils; // повторный экспорт: проброс
// чужого модуля дальше
❗️ export namespace открывает только то, что объявлено в этом блоке. Если позже снова открыть пространство имён net без export, новые имена наружу не уйдут.
❌ Ошибки
• export допустим только в единице, которая начинается с export module …;. В единице реализации (module geometry; без export) это ошибка компиляции
• export нельзя ставить на сущности в безымянном пространстве имён — у них внутреннее связывание
• функцию со static не открыть — она по определению локальна (внутреннее связывание)
• нельзя открывать что-либо из общей вступительной части модуля (того, что идёт до export module …;)
📍Навигация: Вакансии • Задачи • Собесы • Канал в Max
Библиотека C/C++ разработчика
#константная_правильность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++ разработчика
#константная_правильность
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++ разработчика
#под_капотом1, сравниваем с 1 — не сходится. Призраки?
struct Flags { int active : 1; };
int main() {
Flags f;
f.active = 1;
if (f.active == 1)
std::cout << "ok\n"; // не печатает!
}
Задача: объясни, почему однобитное знаковое поле хранит не то, что ждёшь, и какое значение реально читается. Как объявить поле правильно?
💬 Кто наступал на эти грабли — пишите в комментариях.
📍Навигация: Вакансии • Задачи • Собесы • Канал в Max
Библиотека C/C++ разработчика
#междусобойчикstd::ranges::* принимают диапазоны целиком и поддерживают проекции. Если пропустили предыдущий пост про алгоритмы поиска — начните с него.
🧋 ranges::sort — классическая сортировка
std::vector<int> v = {5, 3, 1, 4, 2};
std::ranges::sort(v); // {1, 2, 3, 4, 5}
std::ranges::sort(v, std::greater{}); // {5, 4, 3, 2, 1}
Один аргумент вместо пары итераторов. Второй аргумент — компаратор: std::greater{} для сортировки по убыванию, {} (или ничего) — по возрастанию.
❗️ ranges::sort требует random access range — std::vector, std::array, std::deque подойдут, а std::list — нет (для него есть метод list::sort()).
🍿 ranges::stable_sort — сохраняем порядок равных
struct Task {
std::string name;
int priority;
};
std::vector<Task> tasks = {
{"Почта", 2}, {"Код", 1}, {"Тесты", 2}, {"Деплой", 1}
};
std::ranges::stable_sort(tasks, {}, &Task::priority);
// {{"Код", 1}, {"Деплой", 1}, {"Почта", 2}, {"Тесты", 2}}
// Элементы с одинаковым priority сохранили исходный порядок
Если два элемента «равны» по компаратору, stable_sort гарантирует, что их взаимный порядок останется таким же, как в исходном диапазоне. Обычный sort такой гарантии не даёт.
🍨 ranges::partial_sort — сортируем только первые N
std::vector<int> v = {5, 3, 1, 4, 2};
std::ranges::partial_sort(v, v.begin() + 3);
// {1, 2, 3, ?, ?} — первые три отсортированы, остальные в произвольном порядке
Полезно, когда нужен «топ-N» без затрат на полную сортировку. Сложность O(N·log(K)) вместо O(N·log(N)), где K — количество нужных элементов.
🍋 ranges::partial_sort_copy — топ-N в отдельный буфер
std::vector<int> v = {5, 3, 1, 4, 2};
std::vector<int> top3(3); // буфер под результат
std::ranges::partial_sort_copy(v, top3);
// top3 == {1, 2, 3}
// v не изменился: {5, 3, 1, 4, 2}
Работает как partial_sort, но не трогает исходный диапазон — результат пишется в отдельный контейнер. Размер приёмника определяет K (сколько элементов попадёт в «топ»). Удобно, когда исходные данные нельзя модифицировать.
// Топ-2 самых старших — без изменения исходного вектора
std::vector<Person> oldest(2);
std::ranges::partial_sort_copy(people, oldest, std::greater{}, &Person::age);
👀 ranges::nth_element — найти N-й по порядку
std::vector<int> v = {5, 3, 1, 4, 2};
std::ranges::nth_element(v, v.begin() + 2);
// v[2] == 3 (медиана)
// Все элементы слева <= 3, справа >= 3, но внутри групп порядок произвольный
Элемент на позиции N оказывается тем же, что стоял бы там после полной сортировки. Идеален для поиска медианы или перцентилей. Средняя сложность — O(N).
🐾 ranges::is_sorted — проверка отсортированности
std::vector<int> a = {1, 2, 3, 4, 5};
std::vector<int> b = {1, 3, 2, 4, 5};
bool ok1 = std::ranges::is_sorted(a); // true
bool ok2 = std::ranges::is_sorted(b); // false
// Найти, где порядок нарушается
auto it = std::ranges::is_sorted_until(b);
// *it == 2 — первый элемент, нарушающий порядок
is_sorted — быстрая проверка перед бинарным поиском или мержем. is_sorted_until возвращает итератор на первый элемент, который «ломает» порядок.
🍕 Проекции — работают и в сортировках
struct Person {
std::string name;
int age;
};
std::vector<Person> people = {{"Алиса", 30}, {"Борис", 25}, {"Вера", 35}};
// Сортировка по возрасту — без лямбды
std::ranges::sort(people, {}, &Person::age);
// {{"Борис", 25}, {"Алиса", 30}, {"Вера", 35}}
// По убыванию возраста
std::ranges::sort(people, std::greater{}, &Person::age);
// Топ-2 самых старших
std::ranges::partial_sort(people, people.begin() + 2, std::greater{}, &Person::age);
is_sorted — быстрая проверка перед бинарным поиском или мержем. is_sorted_until возвращает итератор на первый элемент, который «ломает» порядок.
❗️ Проекция — третий аргумент (после компаратора). {} на месте компаратора означает std::less{} по умолчанию.
📍Навигация: Вакансии • Задачи • Собесы • Канал в Max
Библиотека C/C++ разработчика
#константная_правильностьPython: Мощный упор на практику 210 тестов и 243 интерактивные задачи. Программа построена грамотно: вас проведут от стартовой настройки PyCharm, систем счисления и таблицы ASCII через нюансы типа Decimal к серьезной работе с матрицами в NumPy и функциональным встроенным инструментам вроде map(), filter() и reduce().з C++: Тоже не дадут расслабиться внутри 205 тестов и 197 интерактивных задач для жесткой прокачки синтаксиса и алгоритмического мышления.👉 Забираем в закладки: - C++ - Python 🔹 Курс «Программирование на языке Python» 🔹 Получить консультацию менеджера 🔹 Сайт Академии 🔹 Сайт Proglib 🏃♀️ Азбука айтишника #магиякода
