fa
Feedback
C++ geek

C++ geek

رفتن به کانال در Telegram

Учим C/C++ на примерах

نمایش بیشتر
3 611
مشترکین
اطلاعاتی وجود ندارد24 ساعت
-17 روز
-3630 روز
آرشیو پست ها
🧵 Сегодня покажу вам простой, но полезный приём для оптимизации копирования std::vector. Часто вижу такую конструкцию:

std::vector<int> result;
result = getVector();
Если getVector() возвращает временный объект, то копирование можно избежать, используя std::move или Return Value Optimization (RVO). Но вот интересное: если вы точно знаете, что копия не нужна, используйте std::vector::swap с временным объектом:

std::vector<int> result;
std::vector<int> tmp = getVector();
result.swap(tmp);
Почему это может быть лучше? 🔸 Быстрая реализация через указатели. 🔸 Не вызывает лишние аллокаторы. 🔸 Не зависит от move конструктора. 🔸 Гарантированно не бросает исключений, если swap noexcept (что обычно так). В новых компиляторах result = std::move(tmp) даст тот же эффект, но swap — это старый добрый способ, который работает предсказуемо. 🧠 Подумайте, где можно применить это у себя — особенно если работаете с большими контейнерами. ➡️ @cpp_geek

Сегодня хочу показать вам один из приёмов, который часто выручает в реальной разработке на C++ — оборачивание C API в безопасные RAII-объекты. Многие библиотеки на C (например, OpenSSL, SQLite, libpng) требуют вручную управлять ресурсами — открывать, закрывать, аллоцировать и освобождать. Это источник ошибок: забыли free(), упустили close(), получили утечку памяти или файлового дескриптора. В C++ мы можем обернуть такие ресурсы в класс с аккуратным деструктором:

class FileHandle {
public:
    explicit FileHandle(FILE* file) : file_(file) {}
    ~FileHandle() {
        if (file_) {
            fclose(file_);
        }
    }

    FILE* get() const { return file_; }

private:
    FILE* file_;
};
Теперь, даже если функция выбросит исключение или произойдет выход из области видимости, файл закроется автоматически! Такие классы легко комбинировать с std::unique_ptr через кастомные делетеры для ещё большей безопасности. Не забывайте: RAII (Resource Acquisition Is Initialization) — один из важнейших паттернов для профессионального C++. ➡️ @cpp_geek

🚀 Подборка Telegram каналов для программистов Системное администрирование, DevOps 📌 https://t.me/bash_srv Bash Советы https://t.me/win_sysadmin Системный Администратор Windows https://t.me/sysadmin_girl Девочка Сисадмин https://t.me/srv_admin_linux Админские угодья https://t.me/linux_srv Типичный Сисадмин https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin https://t.me/linux_odmin Linux: Системный администратор https://t.me/devops_star DevOps Star (Звезда Девопса) https://t.me/i_linux Системный администратор https://t.me/linuxchmod Linux https://t.me/sys_adminos Системный Администратор https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало) https://t.me/sysadminof Книги для админов, полезные материалы https://t.me/i_odmin Все для системного администратора https://t.me/i_odmin_book Библиотека Системного Администратора https://t.me/i_odmin_chat Чат системных администраторов https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др. https://t.me/sysadminoff Новости Линукс Linux 1C разработка 📌 https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С https://t.me/DevLab1C 1С:Предприятие 8 https://t.me/razrab_1C 1C Разработчик https://t.me/buh1C_prog 1C Программист | Бухгалтерия и Учёт https://t.me/rabota1C_rus Вакансии для программистов 1С Программирование C++📌 https://t.me/cpp_lib Библиотека C/C++ разработчика https://t.me/cpp_knigi Книги для программистов C/C++ https://t.me/cpp_geek Учим C/C++ на примерах Программирование Python 📌 https://t.me/pythonofff Python академия. https://t.me/BookPython Библиотека Python разработчика https://t.me/python_real Python подборки на русском и английском https://t.me/python_360 Книги по Python Java разработка 📌 https://t.me/BookJava Библиотека Java разработчика https://t.me/java_360 Книги по Java Rus https://t.me/java_geek Учим Java на примерах GitHub Сообщество 📌 https://t.me/Githublib Интересное из GitHub Базы данных (Data Base) 📌 https://t.me/database_info Все про базы данных Мобильная разработка: iOS, Android 📌 https://t.me/developer_mobila Мобильная разработка https://t.me/kotlin_lib Подборки полезного материала по Kotlin Фронтенд разработка 📌 https://t.me/frontend_1 Подборки для frontend разработчиков https://t.me/frontend_sovet Frontend советы, примеры и практика! https://t.me/React_lib Подборки по React js и все что с ним связано Разработка игр 📌 https://t.me/game_devv Все о разработке игр Библиотеки 📌 https://t.me/book_for_dev Книги для программистов Rus https://t.me/programmist_of Книги по программированию https://t.me/proglb Библиотека программиста https://t.me/bfbook Книги для программистов БигДата, машинное обучение 📌 https://t.me/bigdata_1 Big Data, Machine Learning Программирование 📌 https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций https://t.me/rust_lib Полезный контент по программированию на Rust https://t.me/golang_lib Библиотека Go (Golang) разработчика https://t.me/itmozg Программисты, дизайнеры, новости из мира IT https://t.me/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻 https://t.me/nodejs_lib Подборки по Node js и все что с ним связано https://t.me/ruby_lib Библиотека Ruby программиста https://t.me/lifeproger Жизнь программиста. Авторский канал. QA, тестирование 📌 https://t.me/testlab_qa Библиотека тестировщика Шутки программистов 📌 https://t.me/itumor Шутки программистов Защита, взлом, безопасность 📌 https://t.me/thehaking Канал о кибербезопасности https://t.me/xakep_2 Хакер Free Книги, статьи для дизайнеров 📌 https://t.me/ux_web Статьи, книги для дизайнеров Математика 📌 https://t.me/Pomatematike Канал по математике https://t.me/phis_mat Обучающие видео, книги по Физике и Математике https://t.me/matgeoru Математика | Геометрия | Логика Excel лайфхак📌 https://t.me/Excel_lifehack https://t.me/mir_teh Мир технологий (Technology World) Вакансии 📌 https://t.me/sysadmin_rabota Системный Администратор https://t.me/progjob Вакансии в IT

🔥 Сегодня я расскажу про одно коварное поведение std::vector, которое часто становится причиной багов и утечек. 📌 Проблема: Удаление элементов в цикле Многие делают так:

std::vector<int> v = {1, 2, 3, 4, 5};

for (size_t i = 0; i < v.size(); ++i) {
    if (v[i] % 2 == 0) {
        v.erase(v.begin() + i);
    }
}
Но это ошибка! После erase вектор сдвигает все элементы, и индекс i указывает уже не на тот элемент. В результате часть значений пропускается. ✅ Правильный способ — использовать итераторы:

auto it = v.begin();
while (it != v.end()) {
    if (*it % 2 == 0)
        it = v.erase(it);
    else
        ++it;
}
Так вы не теряете элементы и не получаете неопределённое поведение. 🧠 Советы: - Всегда помните, что erase инвалидирует итераторы и индексы. - Если хотите удалять по условию — лучше использовать std::remove_if + erase.

v.erase(std::remove_if(v.begin(), v.end(), [](int x) {
    return x % 2 == 0;
}), v.end());
➡️ @cpp_geek

🧠 Как static в C++ помогает бороться с неожиданностями Сейчас покажу вам интересную особенность ключевого слова static в контексте функций — то, что часто забывают даже опытные разработчики. Представим простую ситуацию:

void logCall() {
    int counter = 0;
    counter++;
    std::cout << "Called " << counter << " times\n";
}
Кажется, всё хорошо… Но функция всегда выводит Called 1 times, потому что переменная counter создаётся заново при каждом вызове. Теперь добавим static:

void logCall() {
    static int counter = 0;
    counter++;
    std::cout << "Called " << counter << " times\n";
}
А вот теперь магия — переменная counter сохраняет своё значение между вызовами! Это отличный способ реализовать простой счётчик, кэш или ленивую инициализацию прямо в функции. 📌 Важно: static делает переменную локальной по области видимости, но глобальной по времени жизни. А вы где применяли static неожиданным образом? Делитесь в комментариях! 👇 ➡️ @cpp_geek

💡 Сегодня покажу вам способ, как удобно логировать enum-значения в C++, не превращая код в кашу из switch и if. 📌 Проблема: у вас есть enum, и вы хотите красиво выводить его в лог или std::cout, но стандартно C++ этого не умеет. Например:

enum class Status {
    Ok,
    Error,
    Timeout
};
Обычно вы пишете:

std::string to_string(Status s) {
    switch(s) {
        case Status::Ok: return "Ok";
        case Status::Error: return "Error";
        case Status::Timeout: return "Timeout";
    }
    return "Unknown";
}
Но есть способ проще и без switch — с помощью макроса и X-макросов:

#define STATUS_ENUM(XX) \
    XX(Ok)               \
    XX(Error)            \
    XX(Timeout)

enum class Status {
#define GENERATE_ENUM(name) name,
    STATUS_ENUM(GENERATE_ENUM)
#undef GENERATE_ENUM
};

inline const char* to_string(Status s) {
    switch(s) {
#define GENERATE_CASE(name) case Status::name: return #name;
        STATUS_ENUM(GENERATE_CASE)
#undef GENERATE_CASE
        default: return "Unknown";
    }
}
Теперь достаточно один раз задать список значений — и не нужно вручную синхронизировать enum и to_string(). ✅ Такой подход легко масштабируется. ✅ Удобно для логирования, отладки и сериализации. Пользуйтесь! ➡️ @cpp_geek

Сегодня покажу вам полезную вещь, которую часто упускают даже опытные C++ разработчики - Альтернативные способы инициализации std::vector. 🔹 std::vector: Инициализация — больше, чем просто {} Многие используют векторы так:

std::vector<int> v = {1, 2, 3};
Но есть и другие варианты, которые помогут сделать код выразительнее, а в некоторых случаях — эффективнее. 🔸 1. Инициализация с количеством элементов и значением

std::vector<int> v(5, 10); // 5 элементов по 10
🔥 Часто полезно, когда нужен предзаполненный буфер. 🔸 2. С использованием std::fill

std::vector<int> v(10);
std::fill(v.begin(), v.end(), 7);
✅ Удобно, когда вектор уже создан, но нужно всё заполнить определённым значением. 🔸 3. std::generate и std::iota

std::vector<int> v(10);
std::iota(v.begin(), v.end(), 1); // 1, 2, 3, ..., 10
🚀 Идеально подходит, когда нужно создать диапазон значений. 🔸 4. Из другой коллекции (через итераторы)

std::list<int> lst = {4, 5, 6};
std::vector<int> v(lst.begin(), lst.end());
🔄 Позволяет гибко конвертировать контейнеры. 🔸 5. Через reserve + emplace_back

std::vector<std::pair<int, int>> v;
v.reserve(3);
v.emplace_back(1, 2);
v.emplace_back(3, 4);
v.emplace_back(5, 6);
🔧 Отлично, когда важна производительность и хочется избежать лишнего копирования. ✅ Совет: Не забывайте про reserve, если знаете итоговый размер вектора — избежите лишних реаллокаций. Надеюсь, вы узнали что-то новое. Поделитесь, какие приёмы чаще используете вы? ➡️ @cpp_geek

👨‍💻 Сегодня покажу вам удобный способ, как избавиться от болей с #include в больших C++ проектах. Когда проект растёт, количество инклудов становится пугающим. Компиляция тормозит, зависимости запутаны, порядок подключения начинает влиять на поведение программы… Знакомо? 📌 Решение — Precompiled Headers (PCH). Это не магия, а вполне рабочая практика. Всё просто: 1. Создаём файл pch.h, в котором собираем самые часто используемые инклюды:

   // pch.h
   #pragma once
   #include <iostream>
   #include <vector>
   #include <map>
   // и т.д.
   
2. Добавляем его в компиляцию с флагом:

   g++ -x c++-header pch.h -o pch.h.gch
   
3. Теперь любой другой файл, который первым инклудит pch.h, компилируется быстрее. ⚡️ Бонус: современные сборочные системы, вроде CMake, умеют работать с PCH почти автоматически. Достаточно:

target_precompile_headers(my_target PRIVATE pch.h)
🧠 Маленький совет: следите, чтобы в pch.h не попадали редко используемые или изменяющиеся файлы — иначе получите обратный эффект. Пользовались ли вы PCH в своих проектах? Какой прирост производительности заметили? ➡️ @cpp_geek

🚀 Сегодня я покажу вам простой, но очень полезный приём в C++: как элегантно управлять временем жизни ресурса с помощью std::unique_ptr и кастомного deleter'а. 📌 Задача: у нас есть не-C++ ресурс, например, FILE* из stdio.h. Мы хотим, чтобы он автоматически закрывался, как только выходит из области видимости. Вместо ручного вызова fclose, используем std::unique_ptr с кастомным deleter'ом:

#include <memory>
#include <cstdio>

int main() {
    // Кастомный deleter для FILE*
    auto fileDeleter = [](FILE* f) {
        if (f) {
            std::puts("Файл закрывается автоматически!");
            std::fclose(f);
        }
    };

    // Умный указатель с кастомным deleter'ом
    std::unique_ptr<FILE, decltype(fileDeleter)> file(std::fopen("data.txt", "r"), fileDeleter);

    if (!file) {
        std::perror("Не удалось открыть файл");
        return 1;
    }

    // Файл будет автоматически закрыт в конце блока main()
}
💡 Такой подход безопаснее, чем fopen/fclose, особенно в реальных проектах с множеством return'ов и исключениями. А главное — код остаётся чистым и идиоматичным. 🔥 А вы используете unique_ptr с кастомным deleter’ом в своём коде? Поделитесь, для чего вы его применяли! ➡️ @cpp_geek

🚀 Подпишись и прокачай свои скилы: лучшие каналы для IT-специалистов 👨‍💻📲 Папка с каналами для DevOps, Linux - Windows СисАдминов 👍 Папка с каналами для 1С программистов 🧑‍💻 Папка с каналами для C++ программистов 👩‍💻 Папка с каналами для Python программистов 👩‍💻 Папка с каналами для Java программистов 🖥 Папка с книгами для программистов 📚 Папка для программистов (frontend, backend, iOS, Android) 💻 GitHub Сообщество 🧑‍💻 https://t.me/Githublib Интересное из GitHub Базы данных (Data Base) 🖥 https://t.me/database_info Все про базы данных Разработка игр 📱 https://t.me/game_devv Все о разработке игр БигДата, машинное обучение 🖥 https://t.me/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning QA, тестирование 🖥 https://t.me/testlab_qa Библиотека тестировщика Шутки программистов 📌 https://t.me/itumor Шутки программистов Защита, взлом, безопасность 💻 https://t.me/thehaking Канал о кибербезопасности https://t.me/xakep_2 Хакер Free Книги, статьи для дизайнеров 🎨 https://t.me/ux_web Статьи, книги для дизайнеров Математика 🧮 https://t.me/Pomatematike Канал по математике https://t.me/phis_mat Обучающие видео, книги по Физике и Математике Excel лайфхак🙃 https://t.me/Excel_lifehack Технологии 🖥 https://t.me/tikon_1 Новости высоких технологий, науки и техники💡 https://t.me/mir_teh Мир технологий (Technology World) Вакансии 💰 https://t.me/sysadmin_rabota Системный Администратор https://t.me/progjob Вакансии в IT https://t.me/rabota1C_rus Вакансии для программистов 1С

🔧 Что делать, если std::sort тормозит? Привет! Сегодня хочу поделиться с вами одной типичной ситуацией, с которой сталкивался не раз — сортировка больших контейнеров через std::sort, которая неожиданно начинает тормозить. Вызываешь вроде обычную сортировку, а работает медленно. Почему так? 🔍 Проблема — не std::sort, а компаратор! В 90% случаев проблема не в std::sort, а в лямбде или компараторе, который вы передаёте. Особенно если он: 1. Вызывает копирование: вы сравниваете по значениям, а не по ссылке. 2. Делает что-то тяжёлое внутри: например, вызывает метод, делает std::string копию, обращается к БД (да, и такое видел!). 3. Некеширует результат: например, каждый раз считает длину строки. ✅ Как ускорить сортировку: - Передавайте данные по ссылке, особенно если у вас вектор структур:

  std::sort(vec.begin(), vec.end(), [](const MyStruct& a, const MyStruct& b) {
      return a.key < b.key;
  });
  
- Если у вас есть вычисление ключа — используйте схему "decorate-sort-undecorate":

  std::vector<std::pair<int, size_t>> temp;
  for (size_t i = 0; i < vec.size(); ++i)
      temp.emplace_back(compute_key(vec[i]), i);

  std::sort(temp.begin(), temp.end());
  std::vector<MyStruct> result;
  for (const auto& [_, i] : temp)
      result.push_back(vec[i]);
  
🧠 Мораль: Если std::sort "медленный", не спешите винить алгоритм. Лучше проверьте, что вы передаёте ему на вход. ➡️ @cpp_geek

В апреле россияне могут бесплатно записать детей 8–17 лет на программу льготного обучения программированию. Цель программы —
В апреле россияне могут бесплатно записать детей 8–17 лет на программу льготного обучения программированию. Цель программы — познакомить школьников с IT-профессиями, обучить разработке на Python, созданию 3D-игры и мультфильмов. Участники получат именные сертификаты, которые помогут при поступлении в вуз и в будущей карьере. Онлайн-курс проводит федеральная школа программирования Алгоритмика, лауреат премии «Бренд года в России 2024» и участник проекта Сколково. Занятия ведут преподаватели с опытом работы в IT-компаниях, включая Яндекс, Сбер и Иннополис. Запись открыта до конца недели. Для участия нужно выбрать направление по возрасту ребенка и оставить заявку на сайте: https://s.algoritmika.org/jqcpnx?erid=2W5zFJx3y8k

photo content

🔥 Ловим баги в C++ на лету с помощью AddressSanitizer (ASan) Если valgrind — это медленный, но подробный детектив, то ASan — это охрана, которая ловит баги прямо во время исполнения. Быстро, точно, удобно. 💡 Что такое ASan? Это часть компилятора (clang или gcc), которая вставляет дополнительные проверки в бинарник. Работает во время запуска, ловит: - выход за границы массива, - use-after-free, - double free, - утечки памяти (с флагом LeakSanitizer). 👨‍💻 Пример:

// asan_example.cpp
#include <iostream>

int main() {
    int* arr = new int[5];
    arr[10] = 42; // выход за границу
    delete[] arr;
    return 0;
}
⚙️ Компиляция с ASan:

g++ -fsanitize=address -g asan_example.cpp -o app
🚀 Запуск:

./app
📄 Результат:
==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000050
READ of size 4 at 0x602000000050 thread T0
    #0 0x... in main asan_example.cpp:6
📌 Плюсы ASan: - Мгновенная обратная связь; - Прост в использовании; - Отлично работает с CI (GitHub Actions, GitLab CI и т.д.); - Поддерживает LeakSanitizer (-fsanitize=leak). 📉 Минусы: - Увеличивает размер бинарника; - Иногда мешает оптимизациям; - Не ловит всё (например, утечки в сторонних lib без debug info). 🔧 Совет: Запускай тесты с -fsanitize=address в debug-сборках. Это бесплатно и спасает от кучи головной боли в будущем. 🧵 Используешь ли ты ASan в своих проектах? Или только valgrind? Пиши в комментах👇 ➡️ @cpp_geek

🔧 Как ловить утечки памяти в C++ за 5 минут Инструмент — valgrind. Когда пишем на C++, особенно без smart pointers, утечки памяти — обычное дело. Часто их даже не видно. А valgrind — это наш рентген. 👣 Быстрый гайд: 1. Установи valgrind:

   sudo apt install valgrind
   
2. Собери проект с отладочной информацией:

   g++ -g main.cpp -o app
   
3. Запусти под valgrind:

   valgrind ./app
   
4. И читай отчёт:
   ==12345== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1
   
💡 Фишка: Добавь --leak-check=full и --track-origins=yes — получишь больше деталей, где именно утечка:

valgrind --leak-check=full --track-origins=yes ./app
➡️ @cpp_geek

Баттлы по программированию на C++ прямо в супермаркетах «Перекрёсток» от X5 Group X5 подготовила мерч, скидки и промокоды для
Баттлы по программированию на C++ прямо в супермаркетах «Перекрёсток» от X5 Group X5 подготовила мерч, скидки и промокоды для каждого участника и победителя соревнований. 💡 Другие крутые призы: — фаст-трек на стажировку в X5 Tech для ТОП-25 участников общего рейтинга — 50 000 рублей для ТОП-5 самых быстрых кодеров — в ежедневном розыгрыше: сертификат на 3 000 рублей на покупки в «Перекрёстке» Пора воспользоваться своими скиллами — успей принять участие с 9 по 19 апреля! 📌 Подробнее о соревновании на сайте.

🎯 Как избежать макросов в C++ и остаться довольным Сегодня я покажу вам, как можно избавиться от макросов в C++ и заменить и
🎯 Как избежать макросов в C++ и остаться довольным Сегодня я покажу вам, как можно избавиться от макросов в C++ и заменить их на более безопасные и выразительные конструкции. 🔴 Проблема: #define — это зло. Они не уважают область видимости, не отлаживаются нормально, не подчиняются типам и могут вызвать кучу проблем, особенно в больших проектах. 👉 Вместо #define PI 3.14 Используем:

constexpr double PI = 3.14;
👉 Вместо #define SQUARE(x) ((x)*(x)) Используем шаблон:

template<typename T>
constexpr T square(T x) {
    return x * x;
}
👉 Вместо #ifdef DEBUG ... #endif Используем:

#ifdef DEBUG
inline constexpr bool is_debug = true;
#else
inline constexpr bool is_debug = false;
#endif
А дальше просто:

if constexpr (is_debug) {
    std::cout << "Debug mode\n";
}
💡 constexpr, inline, template и if constexpr — это ваш новый арсенал для выразительного и безопасного кода без макросов. ➡️ @cpp_geek

🧵 RAII — главный секрет устойчивого к утечкам C++ кода Привет! Сегодня хочу напомнить о технике, без которой невозможно писа
🧵 RAII — главный секрет устойчивого к утечкам C++ кода Привет! Сегодня хочу напомнить о технике, без которой невозможно писать безопасный и устойчивый C++ код — это RAII (Resource Acquisition Is Initialization). RAII — это идиома, в которой захват ресурса (файл, сокет, память, мьютекс) происходит в конструкторе объекта, а освобождение — в деструкторе. Благодаря этому ресурсы освобождаются автоматически, даже при исключениях. Пример:

#include <fstream>

void saveData(const std::string& filename) {
    std::ofstream file(filename); // открытие файла
    if (!file.is_open())
        throw std::runtime_error("Cannot open file");

    file << "some data"; // файл закроется автоматически
}
RAII делает твой код: ✅ Безопасным к утечкам ✅ Устойчивым к исключениям ✅ Лёгким для чтения и сопровождения 💡 Совет: всегда оборачивай "ручные" ресурсы в обёртки — std::unique_ptr, std::lock_guard, std::ofstream, std::thread и т.д. ➡️ @cpp_geek

❓ Знали, что разработчики на С++ тоже могут эффективно автоматизировать инфраструктуру с помощью Terraform и GitLab? ⏰ 3 апре
❓ Знали, что разработчики на С++ тоже могут эффективно автоматизировать инфраструктуру с помощью Terraform и GitLab? ⏰ 3 апреля в 20:00 мск на открытом уроке Вячеслав Федосеев объяснит, как разработчикам на С++ настроить CI/CD-пайплайны, управлять конфигурациями и легко разграничивать окружения. Вячеслав — эксперт в IT с 2006 года, прошёл путь от первых Linux-серверов до масштабных DevOps-решений. Автор и ментор курсов по CI/CD и DevOps-практикам. Если вы С++ разработчик, хотите упростить инфраструктуру ваших проектов и ускорить процессы — урок точно для вас. Освойте актуальные практики IaC и получите навыки, которые повысят вашу востребованность. 🎁 Участникам вебинара дарим скидку на полный курс по CI/CD на основе GitLab. 👉 Для участия зарегистрируйтесь Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru

Как упростить дебаг через std::format и std::source_location Когда вы отлаживаете сложный баг, бывает сложно быстро понять, г
Как упростить дебаг через std::format и std::source_location Когда вы отлаживаете сложный баг, бывает сложно быстро понять, где и почему произошла ошибка. С C++20 стало гораздо проще автоматизировать логирование и сделать его по-настоящему информативным. Вот пример:

#include <iostream>
#include <format>
#include <source_location>

void log(const std::string& message,
         const std::source_location location = std::source_location::current())
{
    std::cout << std::format("[{}:{} - {}] {}\n",
                             location.file_name(),
                             location.line(),
                             location.function_name(),
                             message);
}

int divide(int a, int b)
{
    if (b == 0) {
        log("Попытка деления на ноль");
        return 0;
    }
    return a / b;
}
📌 Этот код выведет:
[main.cpp:16 - divide] Попытка деления на ноль
Вы больше не пишете руками __FILE__, __LINE__ и __func__. Всё это делает std::source_location. А с std::format — красиво и читаемо. ➡️ @cpp_geek