Хотите безопасную сериализацию? Создайте концепт для проверки того, что тип можно сериализовать и десериализовать.
#include <concepts>
#include <iostream>
#include <string>
#include <sstream>
// Концепт для сериализуемых типов
template<typename T>
concept Serializable = requires(T obj, std::ostream& os, std::istream& is) {
{ obj.serialize(os) } -> std::same_as<void>;
{ T::deserialize(is) } -> std::same_as<T>;
};
// Пример сериализуемого класса
struct Person {
std::string name;
int age;
void serialize(std::ostream& os) const {
os << name << " " << age;
}
static Person deserialize(std::istream& is) {
Person p;
is >> p.name >> p.age;
return p;
}
};
// Функция для работы с сериализуемыми объектами
template<Serializable T>
void save_and_load(const T& obj) {
std::stringstream ss;
// Сериализация
obj.serialize(ss);
std::cout << "Serialized: " << ss.str() << std::endl;
// Десериализация
T loaded = T::deserialize(ss);
std::cout << "Deserialized successfully" << std::endl;
}
// Использование
void example() {
Person p{"Alice", 25};
save_and_load(p); // ✅ Работает
// save_and_load(42); // ❌ Ошибка компиляции
}
Библиотека C/C++ разработчика #буст
Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍9❤6
  ⏰ std::chrono — работа со временем
👉 Подключение:
💡 Примеры использования:
Основные типы:
— duration для промежутков времени
— time_point для моментов времени
— clock для источников времени
Часы (clocks):
— system_clock системное время
— steady_clock монотонное время
— high_resolution_clock наивысшая точность
Единицы времени:
— nanoseconds, microseconds, milliseconds
— seconds, minutes, hours
— Пользовательские единицы
Библиотека C/C++ разработчика #буст
Используете time_t и clock() для измерения времени?
std::chrono в C++11 предоставляет типобезопасную работу со временем. Высокая точность, читаемый код и портабельность.👉 Подключение:
#include <chrono>
using namespace std::chrono;
💡 Примеры использования:
auto start = high_resolution_clock::now();
expensive_operation();
auto end = high_resolution_clock::now();
auto duration = duration_cast<milliseconds>(end - start);
std::cout << "Operation took: " << duration.count() << "ms" << std::endl;
std::this_thread::sleep_for(seconds(2)); // Спать 2 секунды
std::this_thread::sleep_for(milliseconds(500)); // Спать 500 мс
std::this_thread::sleep_for(2s); // C++14 literals
Основные типы:
— duration для промежутков времени
— time_point для моментов времени
— clock для источников времени
Часы (clocks):
— system_clock системное время
— steady_clock монотонное время
— high_resolution_clock наивысшая точность
Единицы времени:
— nanoseconds, microseconds, milliseconds
— seconds, minutes, hours
— Пользовательские единицы
Библиотека C/C++ разработчика #буст
🔥11❤1
  ✏️ Промпт дня: Улучшение обработки ошибок
Обработка ошибок — один из самых критичных аспектов разработки на C++. Неправильная обработка исключений может привести к утечкам памяти, неопределенному поведению и краху приложения.
☀️ Решение с помощью AI
Для улучшения системы обработки ошибок в вашем коде используйте следующий промпт:
🧋 Пример трансформации
До:
После (с улучшенной обработкой ошибок):
✏️ Как часто в вашем коде встречаются необработанные ошибки? Пишите в комментариях.
Библиотека C/C++ разработчика #буст
Обработка ошибок — один из самых критичных аспектов разработки на C++. Неправильная обработка исключений может привести к утечкам памяти, неопределенному поведению и краху приложения.
☀️ Решение с помощью AI
Для улучшения системы обработки ошибок в вашем коде используйте следующий промпт:
How can I improve the error handling in my C++ code? [ВАШ КОД]
🧋 Пример трансформации
До:
int divide(int a, int b) {
    return a / b;  // Деление на ноль = краш
}
std::vector<int> readFile(const std::string& filename) {
    std::ifstream file(filename);
    std::vector<int> data;
    int value;
    while (file >> value) {
        data.push_back(value);
    }
    return data;  // Что если файл не открылся?
}После (с улучшенной обработкой ошибок):
#include <stdexcept>
#include <optional>
std::optional<int> divide(int a, int b) {
if (b == 0) {
return std::nullopt;
}
return a / b;
}
std::vector<int> readFile(const std::string& filename) {
std::ifstream file(filename);
if (!file.is_open()) {
throw std::runtime_error("Cannot open file: " + filename);
}
std::vector<int> data;
int value;
while (file >> value) {
data.push_back(value);
}
if (file.bad()) {
throw std::runtime_error("Error reading file: " + filename);
}
return data;
}
✏️ Как часто в вашем коде встречаются необработанные ошибки? Пишите в комментариях.
Библиотека C/C++ разработчика #буст
👍3❤1🤔1
  std::vector<std::vector<int> > с пробелом? Давайте посмотрим, как изменилась работа с типами за 25 лет!//Verbosity nightmare
std::vector<std::pair<std::string, int> > vec; // пробел обязателен!
for (std::vector<std::pair<std::string, int> >::iterator it = vec.begin();
it != vec.end(); ++it) {
// работаем с *it
}
// auto и range-based for
std::vector<std::pair<std::string, int>> vec; // >> теперь OK!
for (auto& item : vec) {
// намного чище!
}
// Не нужно указывать типы
std::vector vec{std::pair{"hello", 42}, {"world", 24}}; // CTAD!
std::optional opt = some_function(); // тип выводится автоматически
// Structured bindings
for (auto [name, value] : vec) {
std::cout << name << ": " << value << "\n";
}
#include <concepts>
template<std::integral T> // Концепты!
auto process(T value) {
return value * 2;
}
// Abbreviated function templates
auto add(std::integral auto a, std::integral auto b) {
return a + b;
}
// if consteval для compile-time проверок
constexpr auto get_value() {
if consteval {
return 42; // compile-time версия
} else {
return expensive_runtime_calc(); // runtime версия
}
}
// Multidimensional subscript operator
matrix[1, 2, 3] = value; // вместо matrix[1][2][3]
Библиотека C/C++ разработчика #буст
Please open Telegram to view this post
    VIEW IN TELEGRAM
  🔥10❤2
  😈 Modules в C++20 - будущее или очередной провал?
5 лет назад: "Modules решат все проблемы! Быстрая компиляция! Настоящая инкапсуляция!"
2025 год: Поддержка модулей все еще экспериментальная, build системы путаются, а простой hello world на модулях собирается в 3 раза дольше классического 😅
🐊  Реальность модулей:
- CMake = beta поддержка
- Legacy код = не портируется
- Compile times = пока что хуже
😡  Парадокс: 
Хотели ускорить компиляцию, получили новые проблемы с build системами.
Но справедливости ради - концепция правильная. Проблема в том, что экосистема не готова. Может через 5 лет будет по-другому?
💡 Сравнение:
❓ Вопрос:
Стоит ли уже сейчас изучать modules или подождать еще пару лет?
🔥 Уже использую в пет проектах
⚡️ Изучаю, но не применяю
👾 Жду стабилизации
❤️  Пока что #include рулит
Библиотека C/C++ разработчика #междусабойчик
Modules обещали революцию, а получили головную боль!
5 лет назад: "Modules решат все проблемы! Быстрая компиляция! Настоящая инкапсуляция!"
2025 год: Поддержка модулей все еще экспериментальная, build системы путаются, а простой hello world на модулях собирается в 3 раза дольше классического 😅
- CMake = beta поддержка
- Legacy код = не портируется
- Compile times = пока что хуже
Хотели ускорить компиляцию, получили новые проблемы с build системами.
Но справедливости ради - концепция правильная. Проблема в том, что экосистема не готова. Может через 5 лет будет по-другому?
// Классика: работает везде
#include <iostream>
#include "my_header.h"
// Modules: работает... иногда... если повезет
import std.io;
import my.module;
Стоит ли уже сейчас изучать modules или подождать еще пару лет?
🔥 Уже использую в пет проектах
⚡️ Изучаю, но не применяю
👾 Жду стабилизации
Библиотека C/C++ разработчика #междусабойчик
Please open Telegram to view this post
    VIEW IN TELEGRAM
  ❤31👾18⚡7🔥3
  🔹 Зачем?
Работа с перечислениями (enum) в C++ часто требует дополнительного кода: преобразование в строку, проверка значений, итерация по всем вариантам. Библиотека conjure_enum автоматизирует эту рутину!
🔹 Что умеет?
✅ Генерация to_string() для enum
✅ Проверка валидности значений (is_valid)
✅ Итерация по всем элементам enum
✅ Поддержка enum и enum class
✅ Минимальный оверхед (всё вычисляется на этапе компиляции)
🔹 Пример использования:
#include "conjure_enum.h"
CONJURE_DEFINE_ENUM(Color, Red, Green, Blue)
int main() {
Color c = Color::Green;
std::cout << conjure_enum::to_string(c); // "Green"
std::cout << conjure_enum::is_valid(42); // false
for (Color value : conjure_enum::values<Color>()) { ... }
}
🔹 Плюсы:
✔️ Заголовочный-only (просто подключи conjure_enum.h)
✔️ Не требует C++20 (работает даже на C++11)
✔️ Лёгкая интеграция в существующий код
💡 Кому пригодится?
— Тем, кто устал писать switch-case для enum-ов
— Если нужна удобная отладка (вывод значений в лог)
— Для валидации конфигов/сетевых данных
🔗 Ссылка
Библиотека C/C++ разработчика #буст
Please open Telegram to view this post
    VIEW IN TELEGRAM
  🔥9❤1
  ✅ Чек-лист: Оптимизация времени компиляции
Долгая компиляция убивает продуктивность. Ускорьте сборку вашего C++ проекта.
🎯 Структура проекта
✓ Используйте forward declarations вместо
✓ Минимизируйте зависимости в header файлах
✓ Применяйте
✓ Разбивайте большие файлы на модули
🎯 Современные возможности
✓ Переходите на C++20 modules постепенно
✓ Используйте precompiled headers для стабильных зависимостей
✓ Настройте distributed compilation (distcc, Incredibuild)
🎯 Инструменты и настройки
✓ Включите параллельную компиляцию (-j флаг)
✓ Используйте ccache для кеширования результатов
✓ Профилируйте время компиляции с -ftime-trace (Clang)
✓ Настройте incremental linking
Как измерить результат: Замеряйте время полной и инкрементальной сборки регулярно.
Библиотека C/C++ разработчика #буст
Долгая компиляция убивает продуктивность. Ускорьте сборку вашего C++ проекта.
🎯 Структура проекта
✓ Используйте forward declarations вместо
#include где возможно✓ Минимизируйте зависимости в header файлах
✓ Применяйте
Pimpl idiom для скрытия деталей имплементации✓ Разбивайте большие файлы на модули
🎯 Современные возможности
✓ Переходите на C++20 modules постепенно
✓ Используйте precompiled headers для стабильных зависимостей
✓ Настройте distributed compilation (distcc, Incredibuild)
🎯 Инструменты и настройки
✓ Включите параллельную компиляцию (-j флаг)
✓ Используйте ccache для кеширования результатов
✓ Профилируйте время компиляции с -ftime-trace (Clang)
✓ Настройте incremental linking
Как измерить результат: Замеряйте время полной и инкрементальной сборки регулярно.
Библиотека C/C++ разработчика #буст
❤6🔥5
  При передаче больших объемов данных между процессами или в сетевых операциях происходит множественное копирование данных в память, что создает узкие места по производительности. Особенно критично в высоконагруженных системах реального времени.
Zero-Copy позволяет передавать данные без копирования в пользовательское пространство, используя системные вызовы sendfile() и splice() в Linux.
#include <sys/sendfile.h>
#include <fcntl.h>
// Отправка файла через сокет без копирования в userspace
int send_file_zerocopy(int socket_fd, const char* filename) {
int file_fd = open(filename, O_RDONLY);
off_t offset = 0;
struct stat file_stat;
fstat(file_fd, &file_stat);
// Прямая передача из ядра в сокет
ssize_t sent = sendfile(socket_fd, file_fd, &offset, file_stat.st_size);
close(file_fd);
return sent;
}
• Снижение использования CPU при передаче данных
• Уменьшение задержек за счет исключения системных вызовов copy
• Экономия памяти — данные не загружаются в пользовательское пространство
• Масштабируемость для высоконагруженных веб-серверов и прокси
Библиотека C/C++ разработчика
#буст
Please open Telegram to view this post
    VIEW IN TELEGRAM
  🔥10👍8❤1
  Элегантная работа с multiple return values и сложными структурами.
#include <map>
#include <tuple>
#include <array>
// Функция возвращает несколько значений
std::tuple<int, std::string, double> get_data() {
return {42, "hello", 3.14};
}
struct Point { int x, y; };
int main() {
// 1. Распаковка tuple
auto [id, name, price] = get_data();
std::cout << id << " " << name << " " << price << "\n";
// 2. Распаковка struct
Point p{10, 20};
auto [x, y] = p;
std::cout << "Point: " << x << ", " << y << "\n";
// 3. Распаковка array
std::array<int, 3> arr{1, 2, 3};
auto [first, second, third] = arr;
// 4. Распаковка map::insert результата
std::map<std::string, int> m;
auto [iterator, inserted] = m.insert({"key", 42});
if (inserted) {
std::cout << "Inserted: " << iterator->first << "\n";
}
// 5. Итерация по map с распаковкой
for (const auto& [key, value] : m) {
std::cout << key << " -> " << value << "\n";
}
// 6. Распаковка с модификаторами
auto& [rx, ry] = p; // Ссылки на члены
rx = 100; // Изменяем оригинал
}
Более читаемый код при работе с парами, tuple, структурами
Библиотека C/C++ разработчика
#буст
Please open Telegram to view this post
    VIEW IN TELEGRAM
  ❤10👍3
  🔍 FuzzTest: Фреймворк для фаззинг-тестирования в C++
 
🐼  Что это такое?
🍴  Почему стоит использовать?
✅  Простой синтаксис
✅  Интеграция с GoogleTest
✅  Умная генерация данных — автоматически создаёт осмысленные входные данные для сложных типов: строк, контейнеров, структур
✏️  Пример использования
‼️  Когда использовать?
✅  Парсеры и обработчики пользовательского ввода
✅  Сериализация/десериализация
✅  Криптографические функции
✅  Работа со сложными структурами данных
✅  API, которые должны быть устойчивы к любым входным данным
💌  Github
Библиотека C/C++ разработчика
FuzzTest (от Google) — это библиотека для фаззинг-тестирования C++ кода.FuzzTest — это фреймворк, который автоматически генерирует тысячи тестовых случаев для вашего кода, пытаясь найти крайние случаи, утечки памяти, крэши и другие баги. В отличие от классических unit-тестов, где вы вручную задаёте входные данные, фаззер делает это за вас.void MyTest(int x, const std::string& s) {
  EXPECT_TRUE(MyFunction(x, s));
}
FUZZ_TEST(MySuite, MyTest);#include "fuzztest/fuzztest.h"
void ParseUrlTest(const std::string& url) {
auto result = ParseUrl(url);
// Проверяем, что не крашится на любых входных данных
EXPECT_TRUE(result.has_value() || !result.has_value());
}
FUZZ_TEST(UrlParser, ParseUrlTest)
.WithDomains(fuzztest::Arbitrary<std::string>());
Библиотека C/C++ разработчика
Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍11🤔4❤1
  🎲 std::random vs rand() — генерация случайных чисел
Старый
❌  Старый подход:
🍒  Современный подход:
✏️  Доступные распределения:
• uniform_int_distribution — целые числа
• uniform_real_distribution — вещественные
• normal_distribution — гауссово
• bernoulli_distribution — булево
• exponential_distribution, poisson_distribution и другие
Библиотека C/C++ разработчика
#буст
Старый
rand() из Си имеет множество проблем: плохое качество, ограниченный диапазон, глобальное состояние. В C++11 появились современные генераторы из <random>.#include <cstdlib>
#include <ctime>
srand(time(nullptr)); // Предсказуемо!
int dice = rand() % 6 + 1; // Неравномерное распределение!
double prob = rand() / (double)RAND_MAX; // Плохая точность
#include <random>
// Инициализация генератора (один раз)
std::random_device rd;
std::mt19937 gen(rd()); // Mersenne Twister
// Равномерное распределение [1, 6]
std::uniform_int_distribution dice(1, 6);
int roll = dice(gen);
// Вещественное [0.0, 1.0)
std::uniform_real_distribution prob(0.0, 1.0);
double p = prob(gen);
// Нормальное распределение
std::normal_distribution normal(0.0, 1.0);
double value = normal(gen);
• uniform_int_distribution — целые числа
• uniform_real_distribution — вещественные
• normal_distribution — гауссово
• bernoulli_distribution — булево
• exponential_distribution, poisson_distribution и другие
Библиотека C/C++ разработчика
#буст
Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍12🔥7🌚2👾1
  🦀 Транспиляция кода: от одного языка к другому
Представьте ситуацию: вы нашли идеальное решение на GitHub, но оно написано не на том языке. Или ваш руководитель прочитал статью о новом фреймворке, и теперь нужно переписывать всю кодовую базу. Знакомо?
Хорошая новость: современные LLM-модели отлично справляются с транспиляцией кода между языками программирования.
✏️  Промпт
🍴  Пример использования
Результат:
Библиотека C/C++ разработчика
#буст
Представьте ситуацию: вы нашли идеальное решение на GitHub, но оно написано не на том языке. Или ваш руководитель прочитал статью о новом фреймворке, и теперь нужно переписывать всю кодовую базу. Знакомо?
Хорошая новость: современные LLM-модели отлично справляются с транспиляцией кода между языками программирования.
Rewrite the following code in C++:
[Вставь свой код сюда]
# Исходный Python код
def count_words(text):
"""Count word frequency in text"""
words = text.lower().split()
freq = {}
for word in words:
freq[word] = freq.get(word, 0) + 1
return freq
# Пример использования
text = "hello world hello python world"
print(count_words(text))
# Output: {'hello': 2, 'world': 2, 'python': 1}
Результат:
#include <iostream>
#include <string>
#include <map>
#include <sstream>
#include <algorithm>
std::map<std::string, int> count_words(const std::string& text) {
std::map<std::string, int> freq;
std::istringstream stream(text);
std::string word;
while (stream >> word) {
// Convert to lowercase
std::transform(word.begin(), word.end(), word.begin(), ::tolower);
freq[word]++;
}
return freq;
}
int main() {
std::string text = "hello world hello python world";
auto result = count_words(text);
for (const auto& [word, count] : result) {
std::cout << word << ": " << count << std::endl;
}
return 0;
}
Библиотека C/C++ разработчика
#буст
Please open Telegram to view this post
    VIEW IN TELEGRAM
  👍9❤1👾1
  Чтобы один поток ожидал другого можно воспользоваться condition_variable.
#include <condition_variable>
#include <mutex>
#include <thread>
#include <iostream>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void worker() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return ready; }); // Ждём сигнала
std::cout << "Worker started!\n";
}
int main() {
std::thread t(worker);
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<std::mutex> lock(mtx);
ready = true;
}
cv.notify_one(); // Будим поток
t.join();
return 0;
}
Библиотека C/C++ разработчика
#буст
Please open Telegram to view this post
    VIEW IN TELEGRAM
  ❤3👍2🙏1
  Запуск нового C++ проекта часто начинается с рутины: создание классов с конструкторами, деструкторами, операторами копирования/перемещения, шаблоны паттернов... Звучит очень знакомо и ужасно скучно. Что хотябы немного облегчить себе задачу можно воспользоваться AI.
Хотя AI и не знает бизнес-логику проекта, но зато он отлично справляется с созданием базовой структуры проекта.
Промпт:
Создай boilerplate код для C++ класса ResourceManager,
который управляет игровыми ресурсами (текстуры, звуки).
Класс должен быть синглтоном,
шаблонными методами загрузки/получения ресурсов и
thread-safe доступом.
Результат:
#pragma once
#include <memory>
#include <unordered_map>
#include <mutex>
#include <string>
template<typename T>
class ResourceManager {
private:
std::unordered_map<std::string, std::shared_ptr<T>> resources;
mutable std::mutex mutex;
// Приватный конструктор для синглтона
ResourceManager() = default;
public:
// Удаляем конструктор копирования и оператор присваивания
ResourceManager(const ResourceManager&) = delete;
ResourceManager& operator=(const ResourceManager&) = delete;
// Конструктор и оператор перемещения
ResourceManager(ResourceManager&&) noexcept = default;
ResourceManager& operator=(ResourceManager&&) noexcept = default;
// Деструктор
~ResourceManager() = default;
// Получение единственного экземпляра (Meyer's Singleton)
static ResourceManager& getInstance() {
static ResourceManager instance;
return instance;
}
// Загрузка ресурса
template<typename... Args>
bool load(const std::string& id, Args&&... args) {
std::lock_guard<std::mutex> lock(mutex);
if (resources.find(id) != resources.end()) {
return false; // Уже загружен
}
auto resource = std::make_shared<T>(std::forward<Args>(args)...);
resources[id] = resource;
return true;
}
// Получение ресурса
std::shared_ptr<T> get(const std::string& id) const {
std::lock_guard<std::mutex> lock(mutex);
auto it = resources.find(id);
return (it != resources.end()) ? it->second : nullptr;
}
// Выгрузка ресурса
bool unload(const std::string& id) {
std::lock_guard<std::mutex> lock(mutex);
return resources.erase(id) > 0;
}
// Очистка всех ресурсов
void clear() {
std::lock_guard<std::mutex> lock(mutex);
resources.clear();
}
};
• Полностью рабочий шаблонный класс
• Thread-safe операции
Теперь можешь сразу добавлять свою бизнес-логику, вместо того чтобы тратить время на шаблонный код
Библиотека C/C++ разработчика
#буст
Please open Telegram to view this post
    VIEW IN TELEGRAM
  🥱9👍4❤1
  🎫 std::latch — одноразовый счетчик
🩹  Проблема: 
Главный поток должен дождаться завершения инициализации в нескольких рабочих потоках перед началом основной работы. Барьер не подходит, так как нужна одноразовая синхронизация, а не переиспользуемая.
💡  Решение: 
✏️  Пример кода:
‼️  Преимущества:
• Простая одноразовая синхронизация множества потоков
• Эффективное ожидание без активных проверок
• Идеален для сценариев типа ждать «готовности всех»
• Минимальные накладные расходы по сравнению с
Библиотека C/C++ разработчика
#буст
Главный поток должен дождаться завершения инициализации в нескольких рабочих потоках перед началом основной работы. Барьер не подходит, так как нужна одноразовая синхронизация, а не переиспользуемая.
std::latch (C++20) — это одноразовый счетчик обратного отсчета. Потоки уменьшают счетчик, а другие ждут, пока он достигнет нуля. После срабатывания latch нельзя переиспользовать.#include <iostream>
#include <thread>
#include <latch>
#include <vector>
void worker_init(int id, std::latch& ready_signal) {
// Имитация инициализации ресурсов
std::cout << "Поток " << id << " инициализируется...\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100 * id));
std::cout << "Поток " << id << " готов\n";
ready_signal.count_down(); // Уменьшаем счетчик
}
void worker_process(int id, std::latch& start_signal) {
std::cout << "Поток " << id << " ждет сигнал старта...\n";
start_signal.wait(); // Ждем пока счетчик станет 0
std::cout << "Поток " << id << " начал обработку\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
int main() {
const int num_workers = 4;
std::latch all_ready(num_workers); // Счетчик для готовности
std::latch start_work(1); // Сигнал для старта
std::vector<std::thread> threads;
// Создаем рабочие потоки
for (int i = 0; i < num_workers; ++i) {
threads.emplace_back([i, &all_ready, &start_work]() {
worker_init(i, all_ready);
worker_process(i, start_work);
});
}
// Главный поток ждет готовности всех
std::cout << "Главный поток ждет инициализации...\n";
all_ready.wait();
std::cout << "Все потоки готовы. Даем сигнал старта!\n";
start_work.count_down(); // Даем сигнал старта
for (auto& t : threads) {
t.join();
}
return 0;
}
• Простая одноразовая синхронизация множества потоков
• Эффективное ожидание без активных проверок
• Идеален для сценариев типа ждать «готовности всех»
• Минимальные накладные расходы по сравнению с
condition_variableБиблиотека C/C++ разработчика
#буст
Please open Telegram to view this post
    VIEW IN TELEGRAM
  ❤11👍6🔥4
  Разработчикам часто нужно разделить коллекцию на две группы: элементы, удовлетворяющие условию, и остальные. Ручная реализация требует дополнительных контейнеров или сложной логики с несколькими проходами по данным.
Алгоритм
std::partition переупорядочивает элементы так, что все удовлетворяющие предикату оказываются в начале. Возвращает итератор на границу разделения. #include <algorithm>
#include <vector>
std::vector<int> numbers = {1, 5, 2, 8, 3, 9, 4, 7, 6};
// Разделяем на четные и нечетные
auto boundary = std::partition(numbers.begin(), numbers.end(),
[](int n) {
return n % 2 == 0; // Четные в начало
}
);
// Теперь numbers = {6, 4, 2, 8, 3, 9, 5, 7, 1}
// boundary указывает на первый нечетный элемент
// Обрабатываем только четные числа
for (auto it = numbers.begin(); it != boundary; ++it) {
*it *= 2; // Удваиваем четные
}
• Эффективность: работает in-place без дополнительной памяти O(1)
• Скорость: линейная сложность O(n) за один проход
• Стабильность: существует
std::stable_partition для сохранения порядка• Универсальность: подходит для любых типов данных с произвольным предикатом
Библиотека C/C++ разработчика
#буст
Please open Telegram to view this post
    VIEW IN TELEGRAM
  🔥14👍5❤1