Какой trait определяет, является ли тип числовым?
Anonymous Poll
0%
std::is_arithmetic
0%
std::is_integral
100%
std::is_numeric
🎯 Policy-based Design: шаблонная настройка поведения
Пример реализации:
✅ Вместо наследования от суперкласса составляем объект из политик, что позволяет легко менять поведение без лишнего кода.
Пример реализации:
template<typename ThreadPolicy, typename LogPolicy>
class Engine : private ThreadPolicy, private LogPolicy
{
public:
void run()
{
this->log("Starting...");
this->lock();
this->unlock();
}
};
✅ Вместо наследования от суперкласса составляем объект из политик, что позволяет легко менять поведение без лишнего кода.
Что проще изменить в Policy-based подходе?
Anonymous Poll
0%
Интерфейс базового класса
0%
Структуру иерархии
100%
Поведение
Expression Templates
Или магия ленивых выражений
Шаблоны выражений - это метод метапрограммирования шаблонов C++, который создает структуры, представляющие вычисления во время компиляции, где выражения вычисляются только по мере необходимости для создания эффективного кода для всего вычисления.
Таким образом, шаблоны выражений позволяют программистам обойти обычный порядок вычисления на языке C++ и добиться оптимизации, такой как объединение циклов.
Пример:
🧠 Такие паттерны лежат в основе библиотек Eigen, Blitz++, Armadillo. Они предотвращают создание временных объектов — всё оптимизируется на этапе компиляции.
Или магия ленивых выражений
Шаблоны выражений - это метод метапрограммирования шаблонов C++, который создает структуры, представляющие вычисления во время компиляции, где выражения вычисляются только по мере необходимости для создания эффективного кода для всего вычисления.
Таким образом, шаблоны выражений позволяют программистам обойти обычный порядок вычисления на языке C++ и добиться оптимизации, такой как объединение циклов.
Пример:
template<typename L, typename R>
struct Add
{
L const& l; R const& r;
auto eval() const
{
return l.eval() + r.eval();
}
};
struct Value
{
double v;
auto eval() const
{
return v;
}
};
🧠 Такие паттерны лежат в основе библиотек Eigen, Blitz++, Armadillo. Они предотвращают создание временных объектов — всё оптимизируется на этапе компиляции.
Static Interface (Concepts)
Static Interface: контракты времени компиляции
🧠 Concepts — это compile-time контракты.
Компилятор гарантирует, что тип соответствует интерфейсу.
Это безопасный и быстрый способ добавления ограничений к создаваемым объектам
Static Interface: контракты времени компиляции
template<typename T>
concept Drawable = requires(T obj)
{
obj.draw();
};
template<Drawable T>
void render(T obj)
{
obj.draw();
}
🧠 Concepts — это compile-time контракты.
Компилятор гарантирует, что тип соответствует интерфейсу.
Это безопасный и быстрый способ добавления ограничений к создаваемым объектам
Две ассоциативные структуры, два разных назначения.
map
— Красно-чёрное дерево
— Операции за
O(log n)— Сохраняет сортировку ключей
unordered_map
— Хеш-таблица
— Амортизированная
O(1)— Нет сортировки
Но, может переполняться и ребалансироваться
std::unordered_map<std::string, int> id;
id["Alice"] = 5;
💡 Если нужны сортированные ключи — map. Если нужна скорость — unordered_map.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Что делает map.lower_bound(k)?
Anonymous Poll
25%
Возвращает все итераторы на элементы ≤ k
0%
Возвращает итератор на элемент с ключом ≤ k
75%
Возвращает итератор на первый элемент ≥ k
STL-алгоритмы работают над итераторами, а не над контейнерами — поэтому они универсальны.
std::vector<int> v = {1, 2, 3, 4};
auto it = std::find(v.begin(), v.end(), 3);
std::reverse(v.begin(), v.end());
std::sort(v.begin(), v.end());Полезные алгоритмы, которые могут быть полезны:
std::partition — разбивает по условию
std::unique — убирает дубликаты (но не меняет размер!)
std::any_of, std::none_of, std::all_of
💡 Комбинируя алгоритмы и лямбды, можно писать универсальный и масштабируемый код.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Современный C++ даёт инструменты для более безопасного кода:
std::optional
Хранит “значение или отсутствие значения”.
std::optional<int> try_parse(const std::string& s);
std::variant
Безопасный
union, работающий через типы.variant<int, string> v = "hello";
std::any
Хранит любое значение, но требует приведения типа.
Please open Telegram to view this post
VIEW IN TELEGRAM
Что делает std::visit?
Anonymous Poll
43%
Проверяет variant на тип
57%
Вызывает функцию в зависимости от активного типа
0%
Переводит variant в string
👍4
std::deque — гибрид между std::vector и std::list:
— Быстрые вставки в начало и конец
— Почти такой же быстрый доступ по индексу, как у vector
— Не хранит данные в одном непрерывном блоке
std::deque<int> d = {1, 2, 3};
d.push_front(0);
d.push_back(4);Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
std::string_view — неблокирущий, не владеющий срез строки.
— Дешёвый аргумент, парсер, логирование
void log(std::string_view msg) {
std::cout << msg;
}❗️Частая ошибка:
std::string_view sv = std::string("temp"); // UB🎯 Используйте в сигнатурах вместо const std::string&.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
std::priority_queue<int> q;
q.push(5);
q.push(1);
q.push(10);
std::cout << q.top(); // 10
Особенности:
— Нельзя итерироваться
— Нет erase
— Только top/pop/push
— Доступ только к максимальному элементу
🔑 Если вам нужна структура данных “выдай максимум/минимум” — это ваш выбор
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
std::set — дерево
std::unordered_set — хеш-таблица
std::set<int> s;
s.insert(3);
Особенности std::set :
— Сортированные элементы
— Медленнее, но предсказуемо (O(log n))
— Имеет lower_bound/upper_bound
Особенности std::unordered_set
— Быстро — O(1)
— Нет сортировки
— Выгоден для больших объёмов
✅ Если нужно проверить есть ли элемент — std::unordered_set практически всегда быстрее.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🔄 std::transform: функциональный стиль в C++
Преобразует диапазон элемент за элементом
Особенности:
— Применять лямбды к контейнерам
— Копировать с изменением
— Комбинировать два диапазона
⌨️ Если пишете цикл для каждого элемента — почти всегда можно заменить на std::transform.
Преобразует диапазон элемент за элементом
std::vector<int> a = {1,2,3};
std::vector<int> b(3);
std::transform(a.begin(), a.end(), b.begin(), [](int x){ return x * 2; });Особенности:
— Применять лямбды к контейнерам
— Копировать с изменением
— Комбинировать два диапазона
std::transform(a.begin(), a.end(), c.begin(), std::back_inserter(out), std::plus<>{});Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Как сделать очередь с минимальными элементами наверху?
Anonymous Quiz
20%
std::priority_queue<int, vector<int>, greater<int>>
60%
std::priority_queue<int, less<int>>
20%
Никак
👍4
👍4
const int x = 10;
auto a = x;
auto& b = x;
Что здесь происходит?
a — копия, const отброшен
b — ссылка на const int
💡 auto отбрасывает const и ссылку, если они не указаны явно
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
std::string a = "hello";
std::string b = std::move(a);
Многие думают, что a очищается. Это не совсем так...
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4