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

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

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

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

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

#WXSSA
Download Telegram
🧋 Комбинаторы: views::zip и views::enumerate

В прошлый раз мы генерировали диапазоны на лету с помощью iota и repeat. Теперь научимся их комбинировать — объединять несколько источников данных в один поток, не копируя ни байта.


✈️ views::zip — объединение нескольких диапазонов (C++23)

std::vector<std::string> names = {"Алиса", "Борис", "Виктор"};
std::vector<int> scores = {95, 82, 78};

// Получаем пары (имя, балл)
for (auto [name, score] : views::zip(names, scores)) {
std::cout << name << ": " << score << "\n";
}
// Алиса: 95
// Борис: 82
// Виктор: 78


zip заканчивается на самом коротком диапазоне — безопасно при разной длине. Внутри возвращается std::tuple, а structured bindings разбирают его на отдельные переменные.

❗️ views::zip возвращает ссылки на элементы исходных контейнеров. Модификация через structured binding изменит оригинальные данные.


🥨 views::enumerate — индекс + значение (C++23)

std::vector<int> data = {10, 50, 30, 90, 20};

for (auto [i, val] : data | views::enumerate) {
if (val > 40) {
std::cout << "Первое превышение на позиции " << i << "\n";
break;
}
}
// Первое превышение на позиции 1


Раньше для этого приходилось писать views::zip(views::iota(0), data) (см. предыдущий пост про генераторы). Теперь — в одну строку.

❗️ Тип индекса в enumerate — это range_difference_t, а не int или size_t. На практике разница редко бьёт, но при сравнении с size() компилятор может выдать предупреждение о знаковости.


🧊 Главное свойство

Как и все views, zip и enumerate ленивые — они не создают копий и не выделяют память. Это лёгкие обёртки поверх исходных данных, которые вычисляются только при обращении к элементу.


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

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

#константная_правильность
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍1
🪞 Reflection в C++26 — два оператора, которые меняют правила игры

Каждый C++ разработчик хоть раз писал switch-case для превращения enum в строку. C++26 предлагает забыть об этом — в стандарт входит compile-time reflection.

• Появляются два новых оператора: ^^ (reflection operator) и [: :] (splicer). Первый превращает любую C++-сущность — тип, переменную, namespace, шаблон — в значение std::meta::info на этапе компиляции. Второй делает обратное: конвертирует std::meta::info обратно в тип, выражение или шаблон

std::meta::info — это constexpr-хэндл к сущности. По сути, программа получает возможность исследовать собственную структуру в compile-time, не прибегая к макросам или кодогенерации

• Практический пример — generic to_enum_string(). Через std::meta::enumerators_of(^^T) получаем список enumerator-ов, итерируемся по ним с помощью template for, сплайсим значение через [:e:] и достаём имя через std::meta::identifier_of. Добавил новый enumerator — всё работает автоматически

• Для итерации используется std::define_static_array — отдельный proposal C++26, без которого развернуть expansion statement пока не получится

Вместо ручного switch-case, который ломается при каждом добавлении нового значения, reflection даёт обобщённое решение на уровне языка. Никакой кодогенерации, никаких макросов — чистый constexpr-код с полной type safety.


🍴 Подробнее


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

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

#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
18😢3👍2🔥2😁1
Talanto.work - сайт для всех, кто ищет работу в IT.

Мы спарсили за вас все возможные телеграм каналы и сайты с вакансиями исключительно из сферы IT.
Вам не нужно следить за тем, когда выходит вакансия и где, всё это уже сделано за вас.

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

Например: все вакансии по C++

На talanto.work собрано 28.000+ вакансий из разных .ru и иностранных сайтов: разработка, QA, аналитика, DevOps, продакт, дизайн, менеджмент и другие IT/Digital-направления.

Более 1700 вакансий за последний месяц из телеграм каналов.

Что еще есть на сайте:

🟠 Фильтры для нормального поиска
Можно искать по стеку, грейду, зарплате, стране, формату работы, релокации и типу занятости.

🟠 Разбор резюме
Загружаете CV и получаете конкретные рекомендации: что улучшить, какие навыки добавить, где слабая структура и что может мешать пройти ATS.

🟠Проверка соответствия вакансии и резюме
Рядом с вакансией всегда есть кнопочка узнать соответствие, насколько ваш профиль ей подходит. Сервис покажет процент совпадения, сильные стороны и пробелы в резюме

🟠Сопроводительное письмо за 10 секунд
Вставляете вакансию и получаете персональное письмо под конкретную компанию и роль, а не шаблон “прошу рассмотреть мою кандидатуру”.

🟠Уведомления в Telegram
Задаёте фильтры один раз и бот присылает новые подходящие вакансии прямо в Telegram.

Поиск работы в IT сейчас и так сложный. Мы хотим, чтобы вы тратили меньше времени на листание сайтов и больше на точные отклики туда, где у вас реально есть шанс.

✈️ 28.000+ вакансий
🟢Бот с уведомлениями о ваших вакансиях: @TalantoWorkBot
🟢Написать сопровод
🟢Разобрать резюме
🟢Проверить соответствие резюме вакансиям

Реклама. Киренкина Марина Дмитриевна, ИНН 345702417736. Erid 2VtzqwpGgLF
Please open Telegram to view this post
VIEW IN TELEGRAM
😁1
⭐️ Вызов C-функций из Go без Cgo

Если вы работали с Go и вам нужно было вызвать C-библиотеку, то вы наверняка сталкивались с Cgo.

Cgo работает, но тянет за собой целый набор проблем. Нужен C-компилятор на каждой целевой платформе. Кросс-компиляция превращается в боль. Сборка замедляется. Бинарники раздуваются. purego решает всё это, позволяя вызывать C-функции из чистого Go.

Откуда взялся проект

Библиотека выросла из игрового движка Ebitengine. Его авторы портировали движок на чистый Go для Windows, что позволило кросс-компилировать на Windows с любой ОС одной командой GOOS=windows. purego родился, чтобы принести тот же подход на macOS, Linux и другие платформы.

Что даёт purego

Без Cgo отпадает необходимость в C-компиляторе. Вы можете собирать проект под другую платформу, просто задав GOOS и GOARCH. Сборка кешируется целиком как обычный Go-проект и работает быстрее. Бинарники становятся меньше, потому что Cgo генерирует обёртку на C для каждого вызова, а purego этого не делает.

Ещё purego умеет загружать символы из shared-библиотек в рантайме. Это можно использовать как систему плагинов или для FFI-вызовов в библиотеки на других языках, скомпилированные в .so / .dylib / .dll.

purego работает и при CGO_ENABLED=1. Это значит, что можно портировать проект с Cgo на purego постепенно, не переписывая всё разом.

Как это выглядит в коде

API минимальный. Вы открываете библиотеку через Dlopen, затем регистрируете Go-функцию, которая будет вызывать C:
package main

import (
"fmt"
"runtime"

"github.com/ebitengine/purego"
)

func getSystemLibrary() string {
switch runtime.GOOS {
case "darwin":
return "/usr/lib/libSystem.B.dylib"
case "linux":
return "libc.so.6"
default:
panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS))
}
}

func main() {
libc, err := purego.Dlopen(getSystemLibrary(), purego.RTLD_NOW|purego.RTLD_GLOBAL)
if err != nil {
panic(err)
}
var puts func(string)
purego.RegisterLibFunc(&puts, libc, "puts")
puts("Calling C from Go without Cgo!")
}


Обратите внимание на RegisterLibFunc. Вы объявляете переменную с нужной Go-сигнатурой, а purego привязывает её к C-функции по имени. Никаких // #cgo директив, никаких .h файлов.

Когда стоит использовать

purego подходит, если вам нужно вызывать C-библиотеку из Go и при этом важна простота сборки и кросс-компиляция. Типичные сценарии — работа с системными библиотеками, графические движки, аудио, нативные SDK.

Если ваш проект уже плотно завязан на Cgo и работает на одной платформе, смысла переезжать может не быть. Но если вы начинаете новый проект или хотите избавиться от зависимости на C-тулчейн, purego стоит попробовать.

➡️ Репозиторий

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

🐸 Библиотека Go-разработчика

#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍53
😎 Vibe hiring: почему сильные разработчики не проходят собесы, а «приятные» — проходят

Ты решил все задачи, ответил на все вопросы, а оффер получил кто-то другой. Добро пожаловать в эпоху vibe hiring — найма по ощущению, интуиции и «культурному фиту». Разбираемся, что это такое, почему это катастрофа для IT-рынка и что говорят свежие исследования 2026 года.

👉 Статья

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

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

#буст
👍2
🐸 Подборка вакансий для C++-разработчиков за неделю

Разработчик C++ — Офис (Калининград)

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

Junior C++ Developer — Офис/Гибрид (Москва)

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


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

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

#вакансии
👍1😁1
‼️ Задача на выходные

Этот код содержит баг. Необходимо найди его:

#include <ranges>
#include <vector>
#include <iostream>
#include <algorithm>

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

auto sorted_view = vec
| std::views::transform([](int x) { return x; });

std::ranges::sort(sorted_view);

for (auto v : sorted_view) {
std::cout << v << " ";
}
}


Подсказка: views::transform возвращает prvalue. Можно ли сортировать такой view?

Отсортируется ли vec? Если нет — какая ошибка компиляции и почему?


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

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

#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2😁2
📰 Свеженькое из мира C++

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

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

Hello World в 2 МБ — даже простые программы весят сейчас мегабайты, разбираем почему
Reflection в C++26 — два оператора, которые меняют правила игры
Вызов C-функций из Go без Cgo — альтернативный способ вызова C-функции из Go-кода
Vibe hiring — почему сильные разработчики не проходят собесы

📙 Ranges:

Комбинаторы: views::zip и views::enumerate

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

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

#свежак
😁2
🧹 Сколько мусора в ваших #include?

В больших C++-проектах заголовки превращаются в паутину неявных зависимостей. Один рефакторинг — и всё сыплется, потому что кто-то полагался на транзитивный include.

IWYU — инструмент на базе Clang, который анализирует, какие заголовки реально используются в каждом .cc/.cpp-файле, а какие тянутся впустую
• Удаление лишних include сокращает время компиляции
• Инструмент умеет подставлять forward declarations вместо полных include, что дополнительно режет зависимости
• Актуальная версия 0.26 совместима с Clang 22. Проект жив, обновляется под каждый мажорный релиз LLVM

👉 Github

✏️ Используете IWYU на своих проектах или до сих пор чистите include вручную? 👇

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

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

#буст
👾7😁2
😎 Знакомьтесь с экспертом Proglib.academy: AI-архитектор Андрей Носов

Андрей — один из ключевых спикеров нашего курса AgentOps. Он выстраивает архитектуру, которая выживает в суровом проде и активно делится своим опытом.

За что его ценит IT-комьюнити:

🟣 Топ-спикер AI Conf 2026
Его доклад про мифы семантического поиска и провалы Naive RAG стал одним из самых рейтинговых на конференции.


🟣 Эксперт по GraphRAG и Knowledge Graphs
Андрей внедряет инженерный подход в сложные системы, заменяя «слепую веру» в эмбеддинги строгой логикой графов.


🟣 Автор «14 кругов ада для RAG»
Разработал уникальный набор из 14 unit-тестов, на которых ломается стандартный векторный поиск (от слепоты к отрицаниям до конфликта версий).


🟣 Спикер Saint HighLoad
Регулярно выступает на крупнейших хайлоад-площадках, разбирая архитектуру отказоустойчивых ИИ-сервисов.


Андрей упаковал свои наработки в Google Colab, где можно пощупать 14 сценариев ошибок RAG и их решения:

🔗 Забрать Colab-ноутбук

На курсе Андрей отвечает за самые «мясные» блоки: RAG, оркестрацию агентов и их промышленную эксплуатацию.

Узнать больше о программе и обучении у Андрея:
👉 Курс о том, как внедрять AI-логику в бэкенд и сохранять стабильность сервиса

Так, продолжаем знакомить вас с командой?
👍 — Да, ждем новых лиц
🔥 — Пойду тестить Colab Носова
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱4👍2😁21🌚1
🥨 Вложенные диапазоны: 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++ разработчика

#константная_правильность
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥61
🔥 Препроцессор C++ — наследие, от которого не сбежать

Несмотря на все усилия комитета по стандартизации, #include и #define по-прежнему живут в каждом проекте. Препроцессор — это, по сути, отдельный язык, работающий до компиляции, и он ничего не знает о типах, областях видимости и прочих правилах C++.

Главная проблема — текстовая подстановка. Макрос не проверяет типы, не уважает пространства имён и может сломать код в самом неожиданном месте. Классический пример: #define max(a,b) ((a)>(b)?(a):(b)) — попробуйте передать туда i++, и получите двойной инкремент.

Современный C++ предлагает альтернативы почти для каждого сценария: constexpr, consteval, inline-функции, шаблоны. Но полностью убить препроцессор пока не удалось.


✏️ А в вашем проекте много макросов, или удалось от них почти избавиться?


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

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

#междусобойчик
Please open Telegram to view this post
VIEW IN TELEGRAM
5😁1