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

Как запустить своего ии-агента: https://clc.to/tvpmDQ

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

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

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

#WXSSA
Download Telegram
⚠️ Уже завтра стартует курс AgentOps!

Мы собрали на потоке сборную из мастеров IT-рынка. Практики из BigTech научат вас контролировать и отлаживать ИИ-агентов, чтобы они работали предсказуемо и не сливали бюджет на API.

🔥 Заберите 3 курса по цене 1:
● При покупке VIP-тарифа (осталось 4 места) нового потока «Разработка ИИ-агентов» получаете в подарок курс «AgentOps» + ещё один любой курс Академии (например, «Математика для разработки AI», чтобы глубже освоить направление).

● Три курса обойдутся вам всего в 134.000 ₽ вместо 263.000 ₽.

● Доступна удобная беспроцентная рассрочка, платеж можно разбить на несколько комфортных частей.


Хотите прокачать свое портфолио продакшн-кейсом, но пока сомневаетесь? Пройдите наш бесплатный демо-урок, чтобы протестировать формат перед покупкой.

👉 Забрать 3 курса по цене 1 и получить демо-урок
1
😮 Проекции и функции-члены

Проекция — не обязательно указатель на поле. Это может быть указатель на функцию-член или обычная лямбда — главное, чтобы результат вызова можно было сравнивать компаратором.


🥤 Указатель на метод как проекция
std::vector<std::string> words = {"hello", "WORLD", "cpp"};

// Сортируем по длине строки
std::ranges::sort(words, std::less{}, &std::string::size);
// "cpp"(3), "hello"(5), "WORLD"(5)


Механика та же, что и с полями: std::invoke разворачивает &std::string::size в вызов s.size() для каждого элемента. Алгоритму без разницы, поле перед ним или метод — лишь бы было что вызвать.

‼️ Заметьте: "hello" и "WORLD" оба длины 5, и после сортировки остались в исходном порядке относительно друг друга — std::ranges::sort в общем случае не гарантирует стабильность (в отличие от stable_sort), но для проекций это работает точно так же, как для обычного сравнения.


🥑 Метод как предикат

bool all_nonempty = std::ranges::all_of(words, &std::string::size);


Тут проекция подменяет собой ещё и предикат: all_of без явного предиката просто проверяет результат проекции на истинность. size() возвращает size_t, но он неявно приводится к bool — ноль означает пустую строку. Удобно, когда не хочется писать [](const auto& s){ return !s.empty(); }.


🍒 Лямбда — тоже проекция

Всё, что вызывается с одним аргументом и возвращает ключ для сравнения, годится в качестве проекции — в том числе лямбда:

struct Product {
std::string name;
double price;
int stock;
};

std::vector<Product> products = { /* ... */ };

// Самый дешёвый товар в наличии
auto it = std::ranges::min_element(
products | std::views::filter([](const Product& p) { return p.stock > 0; }),
std::less{},
&Product::price
);


Здесь лямбда стоит на своём привычном месте — предикатом для filter, а проекция по-прежнему &Product::price. Три инструмента, три роли: предикат отбирает элементы, проекция выбирает ключ, компаратор задаёт порядок сравнения этого ключа.

‼️ Если бы понадобилась проекция посложнее одного поля — скажем, «цена с учётом скидки» — туда точно так же встала бы лямбда: [](const Product& p) { return p.price * (1 - p.discount); }. Указатель на поле — просто частный случай вызываемого объекта, самый короткий из возможных.


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

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

#константная_правильностьx
Please open Telegram to view this post
VIEW IN TELEGRAM
🥰2
🥤 constexpr добрался до виртуального наследования

C++26 снимает один из последних синтаксических запретов на constexpr — виртуальное наследование. Sandor Dargo разбирает пейпер P3533R2 Ханы Дусиковой.

• Раньше класс с виртуальными базами нельзя было даже сконструировать при константных вычислениях. Constexpr-конструкторы и деструкторы запрещались на уровне синтаксиса

• P3533R2 убирает запрет целиком. Ромбовидное наследование с виртуальной базой теперь работает на этапе компиляции: constexpr auto ch = Child{} компилируется, оба пути ведут к одному субобъекту

• Мотивация практическая: basic_ios виртуально наследует ios_base. Без этого невозможны constexpr-потоки, форматирование потоков и исключения chrono на этапе компиляции

• Понятие constexpr-suitable становится тавтологией и уходит из стандарта. Синтаксических ограничений не остаётся — только правила вычислимости из [expr.const]

• Реализовать в clang несложно: поиск самого внешнего объекта уже есть для виртуальных вызовов, остаётся расширить APValue


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

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

#свежак
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍2
ОПРОС: Ответьте на пару вопросов и получите промокод на все наши курсы! 🎁

Команда Prоglib.аcаdemy готовит к запуску новые продукты, и нам нужна ваша помощь. Мы хотим создавать обучение, которое будет решать ваши реальные карьерные задачи и бить точно в цель.

Поделитесь своим опытом и ожиданиями, чтобы мы сделали наши курсы еще полезнее именно для вас! Заполнение анкеты займет буквально 2–3 минуты, а с нас — скидка на любой наш курс!

👉 Пройти опрос в Яндекс Формах и забрать промокод
🥱3😁1
🧋 Во что обходится безопасность памяти в Rust

Rust проверяет доступ к памяти на этапе выполнения. Исследование на Rust 1.87 показало реальную цену.

• Проверки индексов: 80% циклов не оптимизируются. Оверхед 1–11% в зависимости от кода
• Обязательная инициализация добавляет лишние store-операции. В некоторых случаях +10% накладных расходов. Для буферов есть MaybeUninit
• Правила алиасинга работают на оптимизацию: +1–2% производительности. В C это restrict, который редко используют
• Итераторы и реслайсинг эффективнее сложной индексной арифметики. Проверка происходит один раз вместо каждой итерации

🍕 Результат: Rust генерирует код эквивалентный C, но проверки добавляют оверхеда. Цена за отсутствие UB.


🚀 Доклад

Приемлемо ли это для исключения целого класса уязвимостей? ⤵️


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

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

#свежак
Please open Telegram to view this post
VIEW IN TELEGRAM
7😁2
This media is not supported in your browser
VIEW IN TELEGRAM
📹 Что должен делать агент-оркестратор?

Посмотрите короткий отрывок из вебинара с Дмитрием Юдиным, внутри концентрат инсайтов о ии-агентах. А если хотите погрузиться в тему с головой, у нас доступна и полная запись этого эфира.

Готовы перейти от теории к практике и собрать свой первый продакшн-кейс?

Прямо сейчас действует мощная акция «3 курса по цене 1»:

🔥 При покупке VIP-тарифа нового потока «Разработка ИИ-агентов» вы получаете в подарок хардкорный курс «AgentOps» + ещё один любой курс Академии на ваш выбор!

Выгода в цифрах: два топовых курса по созданию и контролю агентов обойдутся вам всего в 134.000 ₽ вместо 263.000 ₽. Плюс третий курс бонусом (например, можно подтянуть математику для AI). Ваша чистая экономия — 129 000 ₽!

Сомневаетесь, подойдет ли вам формат? Оставьте заявку и пройдите бесплатный демо-урок, чтобы протестировать платформу перед покупкой.

👉 Пройти демо-урок и забрать 3 курса по цене 1
🧦 Итераторы: фундамент диапазонов

Прежде чем строить проекции и алгоритмы поверх диапазонов, стоит вспомнить, на чём диапазон стоит. А стоит он на итераторе — объекте, который умеет всего три вещи: разыменовываться (*it), двигаться вперёд (++it) и сравниваться с концом. Всё остальное — надстройки.


🍟 Итератор без контейнера

Итератору не обязательно указывать в память — он может генерировать значения на лету. Напишем итератор, выдающий числа Фибоначчи:


struct FibIterator {
using value_type = long long;
using difference_type = std::ptrdiff_t;
using iterator_category = std::input_iterator_tag;

long long a = 0, b = 1;
int count = 0;
int max_count;

FibIterator(int n) : max_count(n) {}
FibIterator() : max_count(-1) {} // sentinel (конец)

long long operator*() const { return a; }

FibIterator& operator++() {
auto next = a + b;
a = b;
b = next;
++count;
return *this;
}

FibIterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}

bool operator==(const FibIterator& other) const {
if (other.max_count == -1) return count >= max_count;
return count == other.count;
}
};


Никакого массива за спиной нет: текущее состояние — пара a, b — живёт прямо в итераторе, а operator++ вычисляет следующее число. Разыменование лишь возвращает уже готовое значение, поэтому оно const и дешёвое.


🍔 Сентинел: конец, который не элемент

Обратите внимание на operator==: итератор, созданный по умолчанию, играет роль сентинела — маркера конца. Он не хранит «последнее число Фибоначчи» (его и не существует), а просто отвечает на вопрос «мы уже нагенерировали max_count элементов?».

Это ключевая идея ranges: end() не обязан быть «настоящим» итератором, указывающим за последний элемент. Ему достаточно уметь сравниваться с begin(). Здесь сентинел того же типа, что и итератор, — но в C++20 это может быть и отдельный тип (как std::unreachable_sentinel для бесконечных последовательностей).

‼️ Заметьте: operator!= мы не писали — начиная с C++20 компилятор сам выведет его из operator==. Одной перегрузкой меньше.


🍒 Диапазон — это просто begin() + end()

struct FibRange {
int n;

FibIterator begin() const { return FibIterator{n}; }
FibIterator end() const { return FibIterator{}; }
};

for (long long f : FibRange{10}) {
std::cout << f << " "; // 0 1 1 2 3 5 8 13 21 34
}


Всё, что нужно range-based for и алгоритмам из std::ranges, — пара методов begin()/end(). Никакого наследования, никаких базовых классов: диапазон — это концепт, а не иерархия. Наш FibRange весит один int и генерирует значения лениво — ровно тот же принцип, на котором построены std::views::iota, filter и остальные адаптеры.

‼️ Тег input_iterator_tag здесь честный: пройти последовательность можно только один раз вперёд, ведь каждое разыменование опирается на накопленное состояние. Если бы мы хранили индекс и пересчитывали значение с нуля, можно было бы замахнуться и на forward_iterator — но для генератора это редко нужно.


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

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

#константная_правильностьx
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🙏1
🍙 Задача на выходные: бинарный поиск, который врал 20 лет

Этот баг жил в стандартной библиотеке Java почти десятилетие. Проверьте, найдёте ли вы его в C++-версии за 15 минут.

int binarySearch(const std::vector<int>& a, int key) {
int low = 0;
int high = static_cast<int>(a.size()) - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (a[mid] < key) low = mid + 1;
else if (a[mid] > key) high = mid - 1;
else return mid;
}
return -1;
}


🚨 Задача: На каких входных данных функция сломается и почему? Как исправить одной строкой?


✏️ Кто вспомнит, в чём подвох, без гугла — тот настоящий сеньор. Ответы в комментариях ⤵️


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

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

#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
3
🎬 Как ИИ ускоряет разработку и где ломаются архитектуры

Мы провели открытый вебинар, где разобрали реальные боли проектирования автономных систем. Ольга Лукьянова на практическом кейсе показала, как использовать ИИ-ассистентов для реальных задач. Вы просили запись встречи — она уже в открытом доступе!

Что внутри:

— Как с помощью ИИ быстрее разбираться в незнакомом коде и готовить пулл-реквесты;
— Критерии выбора между одним агентом и мультиагентной системой;
— Разбор популярных архитектурных ошибок и ограничений современных ИИ;
— Практические рекомендации по проектированию и внедрению облачных агентов.

👉 Посмотреть полную запись можно тут:
VK
YouTube

🚀 Хотите пойти дальше открытого вебинара? Если вы готовы перейти от простых промптов к проектированию надежных, отказоустойчивых ИИ-систем, которые не сливают бюджет компании на API, приходите на курс AgentOps. Поток уже стартовал, но двери еще приоткрыты!

👉 Успеть на курс AgentOps
🐸 Подборка вакансий для C++-разработчиков за неделю

C разработчик — Удалённо

Программист C++ — от 200 000 и до 250 000 ₽ Офис (Санкт-Петербург)

C++ Developer — десктоп VPN-клиент (Windows/macOS) Удалённо

Разработчик C++ (Windows) — Офис (Москва)

Разработчик C++ (Windows) — Гибрид (Москва)

Разработчик на C/C++ под Linux — от 250 000 и до 350 000 ₽ Офис/гибрид/удалённо (Москва)

C Developer (Greengage) — Удалённо (Москва)


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

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

#вакансии
👍1😁1
📰 Свеженькое из мира C++

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

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

Куда податься студенту-айтишнику — 20 актуальных программ стажировок в 2026 году
errno: привет из 1970-х — индикатор ошибки из мира Си
constexpr добрался до виртуального наследования — C++26 снимает один из последних синтаксических запретов на constexpr (виртуальное наследование)
Во что обходится безопасность памяти в Rust — смотрим насколько Rust медленнее C++

📙 Ranges:

Проекции и функции-члены
Итераторы: фундамент диапазонов

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

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

#свежак
😁1
🔥 Открытое занятие по AgentOps — курс стартовал!

Сегодня в 19:00 по МСК пройдет первое занятие нового потока, на которое может прийти каждый. Оцените пользу нашего подхода на ретрансляции урока в VK!

👨‍💻 Спикер: Андрей Носов

Тема: Архитектура управления: state machine для AI-агентов

Будем разбираться, как использовать State machine в качестве главного оружия против стохастики (непредсказуемости) LLM.

Что в программе:

● State machine: инварианты и терминальные состояния;
● Паттерны маршрутизации: Supervisor, ReAct, Plan-and-Solve;
● Детекция циклов и настройка аварийных выходов;
● Абстракция от модели: как сделать каркас, который переживет смену LLM/провайдера;
● Адаптация графов под ограничения локальных моделей;
● Версионирование графов и миграции стейта.

Результат занятия: Вы поймете, как спроектировать надежный каркас агента с жестким контролем исполнения и переходов.

👉 Подписывайтесь на нашу группу ВКонтакте, чтобы не пропустить старт трансляции!
😁1
🌪️ Эффект «затишья перед бурей»: что будет с зарплатами и наймом в IT после 2027 года

Затишье 2025-2026 годов кажется концом эпохи, но если посмотреть на три предыдущих кризиса — доткомы, 2008-й и пандемию — картина другая. Разбираю, почему это типичная фаза восстановления и что будет с зарплатами и наймом после 2027-го.

👉 Статья

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

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

#свежак
😁3
Forwarded from Библиотека программиста
This media is not supported in your browser
VIEW IN TELEGRAM
Один из самых удобных способов разобраться в алгоритмах

Algorithm Visualizer показывает, что происходит внутри кода шаг за шагом.

🔜 Внутри — 70+ алгоритмов, интерактивная визуализация и примеры на JavaScript, Java и C++.

Хороший инструмент для подготовки к собеседованиям и изучения алгоритмов.

🔗 Ссылка

🐸 Библиотека программиста
Please open Telegram to view this post
VIEW IN TELEGRAM
👍71
🍕 Что на самом деле измеряет std::chrono::system_clock?

Если думал, что system_clock — это просто текущее время. На деле это отсчёт от эпохи Unix (1 января 1970 года), и его поведение гораздо сложнее, чем кажется.

⚡️ Когда вы вызываете system_clock::now(), ОС читает значение из аппаратного таймера и возвращает разницу между текущим моментом и эпохой. Эта информация синхронизируется с NTP серверами для корректировки дрейфа кварцевого генератора.

auto now = std::chrono::system_clock::now();
// Внутри: берётся значение из /dev/rtc или Windows' GetSystemTimeAsFileTime()
// И преобразуется в количество тиков с 1970-01-01 00:00:00 UTC


❗️ Критическая деталь: если пользователь выставит неправильное время в системе, system_clock вернёт совершенно неправильное значение. Это не баг, это по дизайну — часы должны отражать реальное время.

Для критичных операций, где важна монотонность, используй steady_clock — он не зависит от системного времени и гарантирует, что каждый следующий вызов вернёт значение больше предыдущего.

💡Вывод: system_clock — это связь приложения с реальным миром через батарейку. Если нужна надёжность, используй другие часы.


✏️ Если хочешь более подробный разбор темы времени в C++ ставь ⚡️ или пиши в комментариях ⤵️


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

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

#под_капотом
Please open Telegram to view this post
VIEW IN TELEGRAM
7
🔥 ИИ-выходные: Собери своего AI-агента за 2 дня

Хватит просто читать про ИИ, пора собирать автономные системы руками! 1–2 августа пройдет хардкорный онлайн-интенсив для junior-middle разработчиков.

Формат: теория ➡️ сразу практика. Вы будете управлять AI-инструментами.

🛠️ Как всё пройдет:

День 1 (Суббота): разбираем анатомию агента, подключаем инструменты (shell, GitHub, Postgres) и дебажим трейсы.
День 2 (Воскресенье): собираем собственного агента под вашу задачу, настраиваем Eval + Guardrails (чтобы бот не галлюцинировал) и проводим демо.


Для кого: Вы пишете на Python, работаете с Git и терминалом. (С нуля не подойдет, темп очень быстрый!)

Артефакт на выходе: Рабочий репозиторий с вашим агентом, который не стыдно показать команде.
👨‍💻 Спикер: Алексей Жиряков (Сбер, GenAI).

Места ограничены!

👉 Изучить программу и занять место
🐞 Собственный View-адаптер

Настоящий View в C++20 должен наследовать от std::ranges::view_base или std::ranges::view_interface<T>. Давайте создадим практический пример — stride_view, который пропускает элементы диапазона с заданным шагом.


🥝 Наследование от view_interface

Любой приличный view должен наследоваться от std::ranges::view_interface<T>. Это даёт тебе begin(), end(), size() и прочие плюшки бесплатно.

template<std::ranges::input_range R>
class stride_view : public std::ranges::view_interface<stride_view<R>> {
private:
// Если R уже view, используем R. Иначе — ref_view для безопасности
R base_;
std::ranges::range_difference_t<R> stride_;

public:
stride_view() = default;

stride_view(R base, std::ranges::range_difference_t<R> stride)
: base_(std::move(base)), stride_(stride) {
// Критическая проверка: stride должен быть положительным!
if (stride_ <= 0) {
throw std::invalid_argument("stride must be > 0");
}
}

auto begin() {
return stride_iterator<R>{ std::ranges::begin(base_),
std::ranges::end(base_), stride_ };
}

auto begin() const {
return stride_iterator<R>{ std::ranges::begin(base_),
std::ranges::end(base_), stride_ };
}

auto end() {
return stride_sentinel<R>{};
}

auto end() const {
return stride_sentinel<R>{};
}
};


😏 Видишь? Сохраняем базовый диапазон и размер шага. Дальше — только логика в итераторе.


☝️ Как работает stride_iterator и stride_sentinel

Итератор — это сердце view. На каждый operator++() он прыгает на stride_ позиций вперёд, не переходя за конец диапазона:

template<std::ranges::input_range R>
struct stride_sentinel {};

template<std::ranges::input_range R>
struct stride_iterator {
std::ranges::iterator_t<R> current_;
std::ranges::sentinel_t<R> end_;
std::ranges::range_difference_t<R> stride_;

// Pre-increment: ++it
stride_iterator& operator++() {
// 🔴 Критический момент: проверяем, не за пределами ли мы
for (int i = 0; i < stride_ && current_ != end_; ++i) {
++current_;
}
return *this;
}

// Post-increment: it++
stride_iterator operator++(int) {
auto tmp = *this;
++(*this);
return tmp;
}

auto operator*() const {
return *current_;
}

// Сравнение с концом диапазона через sentinel
bool operator==(const stride_sentinel<R>&) const {
return current_ == end_;
}
};


☝️ Почему sentinel? Потому что begin() и end() могут быть разных типов в C++20 ranges. Это позволяет избежать ошибки типов при сравнении.


⚡️ Пример использования

std::vector v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto strided = stride_view(v, 2);

for (auto x : strided) {
std::cout << x << " "; // 0 2 4 6 8
}


👌 Красиво: не создали новый вектор, просто гуляем по старому с шагом 2. Никакого копирования, только ленивые вычисления!


⚠️ Замечание: В C++23 это уже есть!

for (auto x : v | std::views::stride(2)) {
std::cout << x << " "; // 0 2 4 6 8
}


🫰 std::views::stride уже входит в стандартную библиотеку! Пример выше — исключительно учебный


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

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

#константная_правильность
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥1👾1