uk
Feedback
Библиотека C/C++ разработчика | cpp, boost, qt

Библиотека C/C++ разработчика | cpp, boost, qt

Відкрити в Telegram

Все самое полезное для плюсовика и сишника в одном канале. Как запустить своего ии-агента: https://clc.to/tvpmDQ По рекламе: @proglib_adv Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5bac324c8ba6dcaa1ad17 #WXSSA

Показати більше

📈 Аналітичний огляд Telegram-каналу Библиотека C/C++ разработчика | cpp, boost, qt

Канал Библиотека C/C++ разработчика | cpp, boost, qt (@cppproglib) у мовному сегменті Російська є активним учасником. На даний момент спільнота об'єднує 16 867 підписників, посідаючи 7 486 місце в категорії Технології та додатки та 38 903 місце у регіоні Росія.

📊 Показники аудиторії та динаміка

З моменту свого створення невідомо, проект продемонстрував стрімке зростання, зібравши аудиторію у 16 867 підписників.

За останніми даними від 26 серпня, 2026, канал демонструє стабільну активність. Хоча за останні 30 днів спостерігається зміна кількості учасників на -98, а за останні 24 години на 2, загальне охоплення залишається високим.

  • Статус верифікації: Не верифікований
  • Рівень залученості (ER): Середній показник залученості аудиторії становить 8.43%. Протягом перших 24 годин після публікації контент зазвичай збирає N/A% реакцій від загальної кількості підписників.
  • Охоплення публікацій: В середньому кожен допис отримує 1 422 переглядів. Протягом першої доби публікація в середньому набирає 0 переглядів.
  • Реакції та взаємодія: Аудиторія активно підтримує контент: середня кількість реакцій на один пост – 3.
  • Тематичні інтереси: Контент зосереджений навколо ключових тем, таких як c++, навигация, компилятор, удалёнка, developer.

📝 Опис та контентна політика

Автор описує ресурс як майданчик для висловлення суб'єктивної думки:
Все самое полезное для плюсовика и сишника в одном канале. Как запустить своего ии-агента: https://clc.to/tvpmDQ По рекламе: @proglib_adv Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a5bac324c8ba6dcaa1ad17 #WXS...

Завдяки високій частоті оновлень (останні дані отримано 27 серпня, 2026), канал підтримує актуальність та високий рівень охоплення публікацій. Аналітика показує, що аудиторія активно взаємодіє з контентом, що робить його важливою точкою впливу в категорії Технології та додатки.

16 867
Підписники
+224 години
-197 днів
-9830 день
Архів дописів
🤝 Как уволиться грамотно: 8 шагов, чтобы закрыть все вопросы Если мысль «надо уходить» появляется каждое утро, скорее всего,
🤝 Как уволиться грамотно: 8 шагов, чтобы закрыть все вопросы Если мысль «надо уходить» появляется каждое утро, скорее всего, пора. Но между «хочу уйти» и «ушел грамотно» целая пропасть. Разбираем 8 шагов, которые помогут уйти без скандала, с рекомендациями и чистой совестью. 👉 Подробнее... 📍Навигация: ВакансииЗадачиСобесы Библиотека C/C++ разработчика #буст

✈️ Алгоритмы диапазонов: Алгоритмы поиска Продолжаем разбираться в диапазонах 🙂 std::ranges::* — это переработанные алгоритмы из <algorithm>. Они принимают диапазоны целиком (не нужно писать begin/end) и поддерживают проекции. 👁 ranges::find / ranges::find_if — найти элемент
std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};

// Найти первый элемент, равный 4
auto it = std::ranges::find(v, 4);
if (it != v.end()) {
    std::cout << "Найдено: " << *it << "\n"; // 4
}

// Найти первый элемент, удовлетворяющий условию
auto it2 = std::ranges::find_if(v, [](int x) { return x > 5; });
// указывает на 9
❗️ Возвращают итератор на найденный элемент или end(), если ничего не найдено. В отличие от классического std::find, диапазонная версия принимает контейнер целиком — никаких v.begin(), v.end(). ↗️ ranges::all_of / any_of / none_of — проверки на весь диапазон
std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};

bool all_positive = std::ranges::all_of(v, [](int x) { return x > 0; });
// true — все элементы положительные

bool any_gt_8 = std::ranges::any_of(v, [](int x) { return x > 8; });
// true — есть 9

bool none_neg = std::ranges::none_of(v, [](int x) { return x < 0; });
// true — отрицательных нет
Три алгоритма, одна идея: проверить предикат на всём диапазоне. Ленивые — all_of остановится на первом false, any_of — на первом true. 🧋 ranges::count / ranges::count_if — подсчёт
auto count_ones = std::ranges::count(v, 1);       // 2
auto count_big  = std::ranges::count_if(v, [](int x) { return x > 5; }); // 2 (9, 6)
count — точное совпадение, count_if — по предикату. Возвращают std::ranges::range_difference_t, а не int — на практике это обычно ptrdiff_t. 🍪 ranges::minmax_element — минимум и максимум за один проход
auto [min_it, max_it] = std::ranges::minmax_element(v);
std::cout << *min_it << " " << *max_it; // 1 9
Возвращает пару итераторов {min, max}. Один проход вместо двух отдельных вызовов min_element + max_element. Structured bindings (auto [min_it, max_it]) делают код чище. ❗️ Также доступны ranges::min_element и ranges::max_element по отдельности. А ranges::min / ranges::max возвращают копию значения (не итератор и не ссылку) — учитывайте это для тяжёлых объектов. 🍕 Проекции — суперсила ranges-алгоритмов
struct Person {
    std::string name;
    int age;
};

std::vector<Person> people = {{"Алиса", 30}, {"Борис", 25}, {"Вера", 35}};

// Найти человека по имени — без лямбды!
auto it = std::ranges::find(people, "Борис", &Person::name);
// it->age == 25

// Самый молодой
auto youngest = std::ranges::min_element(people, {}, &Person::age);
// youngest->name == "Борис"

// Все ли совершеннолетние?
bool all_adults = std::ranges::all_of(people, [](int a) { return a >= 18; }, &Person::age);
Проекция — третий (или четвёртый) аргумент. Она «извлекает» нужное поле перед сравнением. Больше не нужно писать громоздкие лямбды вида [](const Person& p) { return p.age; } — достаточно &Person::age. ❗️ Обратите внимание: в find мы передаём std::string{"Борис"}, а не строковый литерал. Литерал "Борис" имеет тип const char*, и хотя неявное преобразование в std::string здесь сработает, явная конструкция делает намерение очевидным. 🩹 Комбинируем с views
std::map<std::string, std::vector<int>> data = {
    {"alpha", {1, 2, 3}},
    {"beta",  {4, 5}},
    {"gamma", {6, 7, 8, 9}},
};

// Сколько значений больше 5 во всех векторах?
auto all_values = data | views::values | views::join;
auto count = std::ranges::count_if(all_values, [](int x) { return x > 5; });
// 4 (6, 7, 8, 9)
views::values извлекает вторые элементы пар (векторы), а views::join разворачивает один уровень вложенности — склеивает все векторы в единый плоский диапазон. Результат можно передать в любой ranges-алгоритм. 📍Навигация: ВакансииЗадачиСобесы Библиотека C/C++ разработчика #константная_правильность

До 31 мая можно забрать любой курс Proglib Academy со скидкой 40% Если давно хотели прокачаться в Python, ML, алгоритмах или
До 31 мая можно забрать любой курс Proglib Academy со скидкой 40% Если давно хотели прокачаться в Python, ML, алгоритмах или AI-агентах, сейчас самое время выбрать программу и начать обучение по сниженной цене. 🎁 Разработка AI-агентов от 49.000 ₽ (вместо 69.000 ₽) Практический курс по разработке AI-агентов для автоматизации задач, работы и собственных проектов 🎁 Курс AgentOps129.000 ₽ (вместо 149.000 ₽) Для разработчиков и LLM-инженеров, которые хотят внедрять AI-логику в бэкенд и сохранять стабильность сервиса. 🎁 Математика для разработки AI-моделей 23.990 ₽ (вместо 31.990 ₽) Практическая база по математике для анализа данных, ML и дальнейшего развития в AI. 🎁 Математика для Data Scienceот 29.990 ₽ (вместо 39.990 ₽) Курс для тех, кто хочет решать задачи, которые дают на собеседованиях на позицию дата-сайентиста в бигтехе. 🎁 ML для старта в Data Science28.990 ₽ (вместо 38.990 ₽) Разберётесь в машинном обучении: от базовых понятий и линейных моделей до ансамблей, бустинга и рекомендательных систем. 🎁 Основы IT для непрограммистов16.990 ₽ (вместо 28.990 ₽) Курс для IT-рекрутеров, маркетологов, проджектов, продактов и всех, кто работает с IT, но не пишет код. 🎁 Архитектуры и шаблоны проектирования27.990 ₽ (вместо 37.900 ₽) Освоите основные паттерны проектирования и прокачаете навыки архитектора программного обеспечения. 🎁 Специалист по ИИ89.000 ₽ (вместо 113.900 ₽) Курс для тех, кто хочет получить профессию в сфере ИИ, собрать портфолио из 5 проектов и научиться разрабатывать сложных AI-агентов. 🎁 Алгоритмы и структуры данных 33.990 ₽ (вместо 57.990 ₽) Подготовитесь к алгоритмическим собеседованиям, разберёте структуры данных и научитесь писать более эффективный код. 🎁 Программирование на языке Python27.990 ₽ (вместо 47.390 ₽) Освоите Python на практике: без сухой теории, с пошаговой прокачкой навыков и итоговым проектом в портфолио. 🙌 Выбирайте курс по ссылке, оставляйте заявку, и менеджер поможет подобрать программу под ваши цели — https://clc.to/GHcYlg

Что выведет программа?
Anonymous voting

📰 Свеженькое из мира C++ Подготовили подборку самых интересных материалов за неделю о разных аспектах программирования и инт
📰 Свеженькое из мира C++ Подготовили подборку самых интересных материалов за неделю о разных аспектах программирования и интересных проектах в мире C++. 😎 Интересное:7 игр сделанных на Unigine Engine — на Unigine Engine всё же пишут игры Хочешь работать на зарубежную компанию из России? — советы по поиску работы за рубежом Почему std::this_thread::sleep_for не гарантирует точную паузу? — разбираемся почему sleep_for(100ms) это гарантия минимального времени ожидания, но не точного 📙 Ranges: Вложенные диапазоны: views::join и views::join_withRanges: другие полезные адаптеры 🔹📍Навигация: ВакансииЗадачиСобесы Библиотека C/C++ разработчика #свежак

‼️ Задача на выходные: lock_guard Проведи ревью кода и найди проблему (если она есть😉).
#include <mutex>
#include <thread>
#include <vector>
#include <iostream>

std::mutex mtx;
std::vector<int> data;

void producer() {
    for (int i = 0; i < 100; ++i) {
        std::lock_guard<std::mutex> lock(mtx);
        data.push_back(i);
    }
}

void consumer() {
    while (true) {
        std::lock_guard<std::mutex> lock(mtx);
        if (data.empty()) {
            // Ждём данные...
            std::this_thread::sleep_for(
                std::chrono::milliseconds(10));
            continue;
        }
        std::cout << data.back() << "\n";
        data.pop_back();
    }
}
Вопрос: что не так с consumer()? Почему lock_guard здесь — плохой выбор и как это исправить? 📍Навигация: ВакансииЗадачиСобесы Библиотека C/C++ разработчика #междусобойчик

‼️ Задача на выходные: lock_guard Проведи ревью кода и найди проблему (ели она конечно есть😉).
#include <mutex>
#include <thread>
#include <vector>
#include <iostream>

std::mutex mtx;
std::vector<int> data;

void producer() {
    for (int i = 0; i < 100; ++i) {
        std::lock_guard<std::mutex> lock(mtx);
        data.push_back(i);
    }
}

void consumer() {
    while (true) {
        std::lock_guard<std::mutex> lock(mtx);
        if (data.empty()) {
            // Ждём данные...
            std::this_thread::sleep_for(
                std::chrono::milliseconds(10));
            continue;
        }
        std::cout << data.back() << "\n";
        data.pop_back();
    }
}
Вопрос: что не так с consumer()? Почему lock_guard здесь — плохой выбор и как это исправить? 📍Навигация: ВакансииЗадачиСобесы Библиотека C/C++ разработчика #междусобойчик

🐸 Подборка вакансий для C++-разработчиков за неделю Unreal engine/С++ developer (gamedev) —Удалёнка C Developer (VoIP / Telecommunications) — Удалёнка Разработчик C++ (Middle) —Офис (Москва) Архитектор ПО (C++ разработчик) — Команда разработки EPC (MME, S-GW, P-GW) C++ red team developer — от 230 000 и до 350 000 ₽ Гибрид (Санкт-Петербург) Senior/Middle C/C++ Developer (System Programming / Embedded) — от 200 000 ₽ Удалёнка Ведущий разработчик С++ — от 250 000 и до 350 000 ₽ Офис/гибрид (Москва) 📍Навигация: ВакансииЗадачиСобесы Библиотека C/C++ разработчика #вакансии

📌 Зачем дата-сайентисту матанализ? Основная компетенция специалиста по Data Science – способность анализировать и интерпрети
+6
📌 Зачем дата-сайентисту матанализ? Основная компетенция специалиста по Data Science – способность анализировать и интерпретировать данные, а математика является фундаментом для начала работы. В карточках мы разбираем основные разделы математики, с которых стоит начать изучение специалисту по анализу данных. Хотите подготовиться к офферу или подтянуть знания? Оставляйте заявку на наш курс по математике для Data Science 💙 P.S. Только до 31 мая на курс (и вообще на все программы Академии) действует СКИДКА 40% А как у вас дела с высшей математикой? ❤️ — Помню всё 🔥 — Знаю основы 🌚 — Ничего не знаю 🏃‍♀️ Proglib Academy

🐾 Почему std::this_thread::sleep_for не гарантирует точную паузу? Если думал, что sleep_for(100ms) остановит поток ровно на 100 мс, то это не так. На деле — это минимальное время ожидания, не точное. Когда ты вызываешь std::this_thread::sleep_for, происходит следующее: поток переводится в состояние WAITING в планировщике ОС. Ядро ставит таймер и убирает поток из очереди на исполнение. Когда таймер срабатывает, поток не просыпается мгновенно — он попадает обратно в ready queue и ждёт, пока планировщик выделит ему квант времени.
auto start = std::chrono::steady_clock::now();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
auto elapsed = std::chrono::steady_clock::now() - start;
// elapsed может быть 102ms, 115ms, даже 130ms
⚡️ На Linux гранулярность таймера по умолчанию — около 1–4 мс (зависит от CONFIG_HZ). На Windows — исторически 15.6 мс, если не вызвать timeBeginPeriod(1) 💡 Если нужна точность ниже миллисекунды — ОС-пауза не подойдёт. Для таких задач используют spin-wait с std::chrono::high_resolution_clock, жертвуя CPU ради точности. 🐸 Учитывай это при реализации любого setPause-подобного механизма в game loop или real-time системах. 📍Навигация: ВакансииЗадачиСобесы Библиотека C/C++ разработчика #константная_правильность

🍳 Ranges: другие полезные адаптеры В прошлый раз мы разобрали views::join и views::join_with — «сплющивание» вложенных диапазонов. Сегодня — подборка адаптеров, которые пригождаются постоянно, но о которых часто забывают. 🍒 views::reverse — обратный порядок
std::vector<int> v = {1, 2, 3, 4, 5};
for (int x : v | views::reverse) {
    std::cout << x << " "; // 5 4 3 2 1
}
❗️ Требует bidirectional_range. Например, views::filter моделирует bidirectional_range, только если исходный диапазон сам bidirectional_range и common_range — так что для vector, deque или list цепочка views::filter(...) | views::reverse работает, а для forward_list или istream_view — нет. 🏝 views::keys и views::values — для пар и map
std::map<std::string, int> ages = {{"Алиса", 30}, {"Борис", 25}};

for (const auto& name : ages | views::keys) {
    std::cout << name << "\n"; // Алиса, Борис
}

for (int age : ages | views::values) {
    std::cout << age << "\n"; // 30, 25
}
Под капотом views::keys — это views::elements<0>, а views::valuesviews::elements<1>. Работает с любым диапазоном, элементы которого моделируют std::pair или std::tuple-подобный тип. 🍍 views::elements<N> — N-й элемент tuple/pair
std::vector<std::tuple<int, std::string, double>> records = {
    {1, "Alice", 3.14},
    {2, "Bob",   2.71},
};

// Берём только строки (индекс 1)
for (const auto& s : records | views::elements<1>) {
    std::cout << s << "\n"; // Alice, Bob
}
Обобщённая версия keys/values — извлекает элемент с индексом N из каждого кортежа. Индекс задаётся на этапе компиляции, поэтому выход за границы — ошибка компиляции, а не UB. 🍕 views::counted — N элементов начиная с итератора
std::vector<int> v = {10, 20, 30, 40, 50};
auto it = v.begin() + 1; // указывает на 20

// 3 элемента начиная с позиции 1
auto three = views::counted(it, 3);
// 20, 30, 40
В отличие от views::take, который работает с диапазоном, counted принимает итератор + количество. Это незаменимо, когда у вас «голый» итератор без парного end — например, указатель указатель на элемент C-массива или результат std::find. ❗️ Ответственность за то, что it + n не выходит за пределы, лежит на вас — проверки в рантайме нет. 🍿 views::all — обернуть в view явно
std::vector<int> v = {1, 2, 3};

// views::all явно создаёт view из контейнера
auto all_view = views::all(v);

// Это полезно при передаче в функции, ожидающие view
Зачем нужен, если | и так оборачивает? Бывает полезно при передаче контейнера в функцию, которая принимает viewable_range, или для хранения view в переменной без auto&&. На практике views::all вызывается неявно почти в каждой цепочке — но иногда явный вызов делает код яснее. 🍋 views::common — сделать begin/end одного типа Многие «классические» алгоритмы и конструкторы контейнеров ожидают, что begin() и end() возвращают один и тот же тип. У ленивых view это часто не так — end() может вернуть sentinel, а не итератор.
auto view = some_range | views::filter(...);

// Если нужно передать в старый алгоритм, требующий итераторов одного типа:
auto common_view = view | views::common;
std::copy(common_view.begin(), common_view.end(), output);
❗️ Если диапазон уже common_range, адаптер ничего не делает — просто пробрасывает как есть. Накладных расходов в этом случае ноль. 🩹 Комбинируем всё вместе
std::map<std::string, std::vector<int>> data = {
    {"alpha", {1, 2, 3}},
    {"beta",  {4, 5}},
    {"gamma", {6, 7, 8, 9}},
};

// Все значения → сплющить → обратный порядок → первые 4
auto result = data
    | views::values
    | views::join
    | views::reverse
    | views::take(4);

for (int x : result) {
    std::cout << x << " "; // 9 8 7 6
}
Ни одного промежуточного контейнера — каждый элемент протягивается через всю цепочку лениво, по требованию. 📍Навигация: ВакансииЗадачиСобесы Библиотека C/C++ разработчика #константная_правильность

🔥 База по экономике токенов и кэшированию от AI Platform Lead из Bitrix24 Знакомьтесь, Сергей Нотевский. AI Platform Lead в
🔥 База по экономике токенов и кэшированию от AI Platform Lead из Bitrix24 Знакомьтесь, Сергей Нотевский. AI Platform Lead в Bitrix24. Он один из ключевых экспертов нашего курса AgentOps. На своих лекциях он детально разбирает экономику AI-агентов, кэширование токенов, LLM-инфраструктуру и вывод генеративных систем в стабильный прод. Мы попросили Сергея поделиться материалами для тех, кто хочет оптимизировать косты на LLM в проде. Сохраняйте методичку по prefix cache метрике, которая напрямую влияет на ваши деньги. Как говорят создатели Manus:
“KV-cache hit rate is the single most important metric for a production-stage AI agent.”
🛠 Что внутри методички (комбо из 3 статей + код):
Экономика кэширования — особенности провайдеров и как правильно считать затраты. Частые анти-паттерны — почему ваш кэш постоянно сбрасывается и вы платите больше. Кэш в AI-агентах — специфика работы с памятью в автономных системах.
🍒 Вишенка на торте: готовый SKILL для агента, который делает ревью вашего проекта, находит анти-паттерны и предотвращает низкое попадание в кэш. — Забрать комбо-материалы на GitHub P.S. Если хотите послушать Сергея вживую — ловите его на конференциях Kode Waves (май), Conversations AI и Highload Spb (июнь). 🎁 Акция в честь старта продаж! Прямо сейчас при покупке Инженерного трека вы получаете полный доступ к материалам курса «Разработка ИИ-агентов» в подарок. 👉 Забрать 2 курса по цене 1 и начать обучение

🌍💸 Хочешь работать на зарубежную компанию из России? Прямой найм почти умер, зато появились EOR-провайдеры. Европа уступила
🌍💸 Хочешь работать на зарубежную компанию из России? Прямой найм почти умер, зато появились EOR-провайдеры. Европа уступила место ОАЭ и Сингапуру. А джуны с английским иногда находят оффер быстрее, чем сеньор на hh.ru. Пять трендов валютной удаленки, о которых стоит знать прямо сейчас. 👉 Подробнее... 📍Навигация: ВакансииЗадачиСобесы Библиотека C/C++ разработчика #буст

🌮 7 игр сделанных на Unigine Engine Когда говорят «C++ игровой движок», все автоматически думают про Unreal. Но UNIGINE тоже
🌮 7 игр сделанных на Unigine Engine Когда говорят «C++ игровой движок», все автоматически думают про Unreal. Но UNIGINE тоже в игре — в буквальном смысле: на нём создают не только тренажёры, но и игры. Движок поддерживает Vulkan, DX12, умеет работать с огромными открытыми мирами благодаря двойной точности координат. Малоизвестная, но интересная штука в мире C++ геймдева. 👉 Видео с пруфами (играми) 📍Навигация: ВакансииЗадачиСобесы Библиотека C/C++ разработчика #буст

🔥 Препроцессор C++ — наследие, от которого не сбежать Несмотря на все усилия комитета по стандартизации, #include и #define по-прежнему живут в каждом проекте. Препроцессор — это, по сути, отдельный язык, работающий до компиляции, и он ничего не знает о типах, областях видимости и прочих правилах C++. Главная проблема — текстовая подстановка. Макрос не проверяет типы, не уважает пространства имён и может сломать код в самом неожиданном месте. Классический пример: #define max(a,b) ((a)>(b)?(a):(b)) — попробуйте передать туда i++, и получите двойной инкремент. Современный C++ предлагает альтернативы почти для каждого сценария: constexpr, consteval, inline-функции, шаблоны. Но полностью убить препроцессор пока не удалось. ✏️ А в вашем проекте много макросов, или удалось от них почти избавиться? 📍Навигация: ВакансииЗадачиСобесы Библиотека C/C++ разработчика #междусобойчик

🥨 Вложенные диапазоны: views::join и views::join_with Сегодня научимся работать с вложенными — «сплющивать» диапазон диапазонов в один поток и вставлять разделители между ними. ☂️ views::join — «сплющить» диапазон диапазонов
std::vector<std::vector<int>> matrix = {{1, 2, 3}, {4, 5}, {6, 7, 8, 9}};

// Объединяем все подвекторы в один поток
for (int x : matrix | views::join) {
    std::cout << x << " "; // 1 2 3 4 5 6 7 8 9
}
Классический кейс — обход всех элементов матрицы без вложенных циклов. join работает с любым диапазоном, элементы которого сами являются диапазонами: vector<vector<T>>, vector<string>, результат views::split и т.д.
std::string csv = "10,20,30";

// split разбивает → join склеивает обратно (без разделителя)
for (char c : csv | views::split(',') | views::join) {
    std::cout << c; // 102030
}
❗️ Важный нюанс: в C++20 views::split возвращает подиапазоны, тип которых отличается от string_view. В C++23 поведение split было пересмотрено, а прежняя версия переименована в views::lazy_split. Если работаете со строками в C++20, имейте это в виду. 🍴 Какую категорию итераторов даёт join? Это зависит от исходного диапазона: • если внешний и внутренний диапазоны моделируют forward_range (как vector<vector<int>>), результат join тоже будет forward_range • итераторы валидны, многопроходность гарантирована • если оба моделируют bidirectional_range и внутренний при этом common_range, результат может быть bidirectional_range • если внешний диапазон — всего лишь input_range (например, поток), результат join — тоже input_range, и тогда проходить его можно только линейно, в один проход ❗️ Категория результата определяется самым «слабым» из участников. 🧋 views::join_with — объединить с разделителем (C++23)
std::vector<std::string> words = {"один", "два", "три"};

// Вставляем пробел между словами
for (char c : words | views::join_with(' ')) {
    std::cout << c;
}
// один два три
Разделителем может быть не только один элемент, но и целый диапазон:
std::vector<std::string> parts = {"SELECT *", "FROM users", "WHERE id = 1"};

for (char c : parts | views::join_with(std::string_view{"\n  "})) {
    std::cout << c;
}
// SELECT *
//   FROM users
//   WHERE id = 1
❗️ join_with требует, чтобы тип разделителя был совместим с внутренним типом элементов. Если у вас vector<vector<int>>, разделитель — int или диапазон int, а не string. Компилятор скажет об этом длинной шаблонной ошибкой — ищите в ней range_value_t. 🩹 Комбинация с другими views Настоящая сила раскрывается в цепочках:
std::vector<std::vector<int>> grid = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

// Сплющить → оставить чётные → взять первые 3
auto result = grid
    | views::join
    | views::filter([](int x) { return x % 2 == 0; })
    | views::take(3);

for (int x : result) {
    std::cout << x << " "; // 2 4 6
}
Ни одного промежуточного контейнера — всё вычисляется поэлементно. 🍋 Главное свойство Как и все views, join и join_with ленивые — они не копируют внутренние диапазоны и не выделяют память. Элементы «вытягиваются» по одному при итерации. Но у этой лени есть цена: join над input_range даёт только input_range, поэтому отсортировать результат напрямую не получится — сначала материализуйте через ranges::to<vector>() (C++23). 📍Навигация: ВакансииЗадачиСобесы Библиотека C/C++ разработчика #константная_правильность