Senior C++ Developer
11.9K subscribers
1.43K photos
3 videos
627 links
Изучаем C++.

По вопросам сотрудничества: @adv_and_pr

РКН: https://www.gosuslugi.ru/snet/676e9a1e4e740947beca35ba
Download Telegram
string at()

std::string::at()
это метод для доступа к символу строки по указанному индексу.
Принимает в качестве аргумента индекс символа типа size_t и возвращает ссылку на символ по данному индексу.

— Индексация начинается с 0 до size()-1.

— Выбрасывает исключение out_of_range, если индекс вне диапазона.

— Более безопасен, чем оператор [], так как проверяет границы.

Полезен в циклах для доступа к каждому символу, когда нужен безопасный доступ для чтения/записи конкретного символа.

#это_база
Лямбда-выражения

Лямбда-выражения (lambda) — это безымянные функции, которые можно использовать для передачи поведения или сравнения.
Объявляются как {body;}, в квадратных скобках указываются аргументы, в фигурных — тело.

Полезны для задания функций сравнения, например в алгоритмах sort(), когда нужно быстро передать функциональность, не создавая отдельную функцию.
Поддерживают захват по значению [=] и по ссылке [&].
Можно сохранить в переменной с помощью auto.

#это_база
#вопросы_с_собеседований
Для чего нужен атрибут maybe_unused?

Атрибут [[maybe_unused]] используется для подавления предупреждений компилятора об неиспользуемых объектах.

Компилятор выдает предупреждение, если объект объявлен, но нигде не используется и чтобы избавиться от ложных предупреждений, например, когда объект используется только в отладочной сборке, применяют [[maybe_unused]].

Позволяет задать политику использования на уровне отдельных объектов и улучшает читаемость кода, явно объясняя причину неиспользования.
#вопросы_с_собеседований
Для чего нужен атрибут fallthrough?

Атрибут [[fallthrough]] используется для явного указания того, что в конструкции switch нужно пропустить break в конце case и перейти к выполнению следующего case.

По умолчанию в С++17 и новее переход между case без break приводит к ошибке компиляции и чтобы сохранить старое поведение и разрешить переход, нужно добавить [[fallthrough]].

Это улучшает читаемость кода, явно указывая на отсутствие break и помогает избежать случайного отсутствия break, когда разработчик забыл его добавить.
[[fallthrough]] также полезен при рефакторинге старого кода с switch в современный стандарт С++.
#вопросы_с_собеседований
Может ли inline-функция быть рекурсивной?

Поскольку компилятор просто встраивает код inline-функции в место вызова, не имеет значения, является ли эта функция рекурсивной или нет. Компилятор будет просто копировать один и тот же код функции при каждом рекурсивном вызове.

Таким образом, рекурсивные inline-функции абсолютно допустимы и часто используются, когда нужна рекурсия без накладных расходов на стандартные вызовы функций.
Алгоритм generate

std::generate
— это алгоритм из стандартной библиотеки C++, который используется для заполнения диапазона элементов сгенерированными значениями.

Принимает три параметра: начало диапазона, конец диапазона и функцию генерации. Функция генерации должна принимать неявный счетчик и возвращать очередное значение.
Для каждого элемента в заданном диапазоне будет вызываться функция генерации, и результат будет записан в этот элемент.

В этом примере std::generate совместно с генератором случайных чисел используется для быстрого заполнения вектора случайными значениями.

#это_база
std::clamp

std::clamp
это функция из стандартной библиотеки, которая позволяет ограничить значение в заданном диапазоне.

Функция принимает значение, нижнюю и верхнюю границы и возвращает исходное значение, если оно входит в диапазон, или же возвращает ближайшую границу, если значение вне диапазона.

Применяется для:

— Ограничения числовых значений в заданных пределах.
— Обработки данных из недостоверных источников.
— Защиты от переполнения/обрезания данных.
— Нормализации данных в ML и компьютерном зрении.
— Реализации игровой логики в движках.
— Обработки аудио- и видео- сигналов.
absl::btree

absl::btree
— это реализация B-дерева в библиотеке Abseil для C++.
Преимущества absl::btree — это хранение данных в отсортированном порядке, быстрый поиск, вставка и удаление за O(logN), поддержка уникальных и неуникальных ключей, реализация set и map.

Применяется в задачах, где нужна высокопроизводительная структура данных с отсортированным доступом, например:

Реализация словарей и сортированных множеств;
Для хранения данных в базах данных;
В поисковых системах для индексов;
В структурах вроде кэша для быстрого доступа;
В задачах машинного обучения для хранения данных.
#вопросы_с_собеседований
Какие отличия у std::array и std::vector?

std::array — это обёртка вокруг обычного массива, фиксированного размера, а std::vector - это динамически расширяемый массив. std::array хранит свои данные в стековой памяти, а vector выделяет память в куче (динамическая память). У std::array в параметрах шаблона указывается тип хранимых элементов и размер массива. А у std::vector - тип элементов и ещё возможно указать аллокатор, который нужно использовать при выделении памяти (с помощью new). std::array чуть лучше по производительности в случае небольшого массива, чем std::vector, который содержит в себе несколько указателей, которые указывают на выделенный в куче кусок памяти.
#вопросы_с_собеседований
Что быстрее: постфиксные инкрементные операторы или префиксные? Чем отличается их сигнатура?

Префиксные операторы быстрее. В постфиксных операторах производится дополнительная операция сохранения предыдущего состояния объекта, а затем только увеличение на 1, а в префиксном операторе после инкрементирования объекта, сразу возвращается ссылка объект.

Сигнатура их отличается фиктивным параметром int у постфиксного оператора.
Автовыведение типа

Несмотря на то, что ключевое слово auto было введено еще в C++11, многие программисты продолжают его игнорировать. А ведь автовыведение позволяет экономить время и делает код лаконичным.

Увидеть преимущества можно даже на примере стандартных типов STL.
this удобно использовать для цепочных вызовов

Мы можем вернуть ссылку на объект, на котором мы вызываем метод класса:

Foo &set(int x) { this->x = x; return *this; }

Здесь метод set возвращает ссылку на объект класса Foo(Foo&). Такая реализация метода позволяет нам писать код, подобный этому:

obj.set(2).set(8);

Это возможно, поскольку первый вызов метода set возвращает указатель на объект obj. Второй метод вызывается на объекте obj, т. е. можно переписать код так:

obj = obj.set(2);
obj = obj.set(8);
Указатель this доступен только внутри нестатических методов класса

Попробуем добавить такой метод в наш класс:

static void set(int x) { this->x = x; }

Здесь мы добавили для метода setмодификатор static.

obj.set(6);

Мы получим ошибку компиляции: ‘this’ is unavailable for static member functions.

Это объясняется тем, что указатель this передаётся только в нестатические методы класса как скрытый параметр. В статических методах он недоступен.
Продвинутый курс лекций по алгоритмам с ФИВТ МФТИ.

https://youtube.com/playlist?list=PL4_hYwCyhAvYzrbNOLAy-EczKdAbWoRDK
Минимально жизнеспособный графический интерфейс на C++.

https://ossia.io/posts/minimum-viable/
Функция before_begin()

forward_list::before_begin() - это встроенная функция в CPP STL, которая возвращает итератор, который указывает на позицию перед первым элементом forward_list.
#вопросы_с_собеседований
Что такое класс хранения?

Класс, который определяет срок существования, компоновку и расположение переменных/функций в памяти.

В C ++ поддерживаются такие классы хранения: auto, static, register, extern и mutable.

Обратите внимание, что register устарел для C++11. Для C++17 он был удален и зарезервирован для будущего использования.
#вопросы_с_собеседований
Что вообще означает модификатор virtual?

В C++ виртуальные функции позволяют поддерживать полиморфизм – одну из ключевых составляющих ООП. С его помощью в классах-потомках можно переопределять функции класса-родителя. Без виртуальной функции мы получаем «раннее связывание», а с ней – «позднюю привязку». То есть, какая реализация метода используется, определяется непосредственно во время выполнения и основывается на типе объекта с указателем на объект, из которого он построен.