C++ geek
3.56K subscribers
251 photos
2 videos
16 links
Учим C/C++ на примерах
Download Telegram
В С++11 появилась такая классная штука, как цикл for, основанный на диапазоне. Например, вам не придётся писать for (int i = 0; i < v.size(); i++), потому что теперь есть for (auto &e : v). Он очень полезен при обходе std::set или std::map.

➡️ @cpp_geek
Длина числа

Для вычисления количества цифр в числе вместо цикла можно эффективно использовать log.

➡️ @cpp_geek
Вы можете написать функцию, которая будет возвращать два и более значений, с помощью std::tuple и std::tie.

➡️ @cpp_geek
Использование emplace_back вместо push_back

В C++ 11 emplace_back работает так же, как push_back, добавляя элементы в конец вектора. emplace_back работает быстрее, так как push_back сначала создает временную переменную, а затем добавляет ее в конец вектора.
➡️ @cpp_geek
Как включить все стандартные библиотеки одной командой

Чтобы разом включить в проект все стандартные библиотеки, используйте #include <bits/stdc++.h>. Это особенно полезно в условиях дефицита времени на соревнованиях по программированию.

Но помните, что:

#include <bits/stdc++.h>
содержит множество заголовочных файлов, которые, возможно, и не понадобятся в конкретном проекте. А это может привести к увеличению времени компиляции.

#include <bits/stdc++.h> не является стандартным заголовочным файлом библиотеки GNU C++. Таким образом, не относящиеся к типу GCC (GNU Compiler Collection) компиляторы могут испытывать затруднения в процессе исполнения. Однако так бывает не часто!
➡️ @cpp_geek
Ссылки в C++

Когда переменная объявляется как ссылка, она становится альтернативным именем для существующей переменной. Переменную можно объявить как ссылку, поместив в её объявление "&".
➡️ @cpp_geek
nullptr

Раньше для обнуления указателей использовался макрос NULL, являющийся нулем — целым типом, что, естественно, вызывало проблемы (например, при перегрузке функций). Ключевое слово nullptr имеет свой собственный тип std::nullptr_t, что избавляет нас от бывших проблем. Существуют неявные преобразования nullptr к нулевому указателю любого типа и к bool (как false), но преобразования к целочисленных типам нет.
➡️ @cpp_geek
Является ли число степенью двойки

Мы можем проверить, является ли число степенью двойки или нет напрямую, используя код выше.
➡️ @cpp_geek
range-based циклы

В С++11 была добавлена поддержка парадигмы for each для итерации по набору. В новой форме возможно выполнять итерации в случае, если для объекта итерации перегружены методы begin() и end().

Это полезно, когда вы просто хотите получить элементы массива/контейнера или сделать с ними что-то, не заботясь об индексах, итераторах или кол-ве элементов.
➡️ @cpp_geek
Алгоритм copy_n

Используется для копирования элементов из одного контейнера в другой.
➡️ @cpp_geek
Строго-типизированный enum

У «традиционных» перечислений в С++ есть некоторые недостатки: они экспортируют свои значения в окружающую область видимости (что может привести к конфликту имен), они неявно преобразовываются в целый тип и не могут иметь определенный пользователем тип.

Эти проблемы устранены в С++11 с введением новой категории перечислений, названных strongly-typed enums. Они определяются ключевым словом enum class. Они больше не экспортируют свои перечисляемые значения в окружающую область видимости, больше не преобразуются неявно в целый тип и могут иметь определенный пользователем тип (эта опция так же добавлена и для «традиционных» перечислений).
➡️ @cpp_geek
Алгоритм iota

Присваивает каждому элементу в диапазоне [first,last) последовательные значения val, как если бы они увеличивались ++val после записи каждого элемента.

➡️ @cpp_geek
Представления (Views)

Представления — это просто-напросто диапазоны, которые дешево копировать и перемещать (за константное время). Из-за этого представление не может владеть элементами, которые просматривает. Одно исключение — std::views::single, которому принадлежит единственный просматриваемый элемент.

Представления компонуются во время компиляции с прицелом на то, что компилятор заинлайнит код.

Например, следующий код последние последние три элемента диапазона. Сначала мы reverse’им диапазон, затем берем первые три элемента и, наконец, снова reverse’им диапазон (обратите внимание, что существует std::views::drop, который делает это напрямую).
➡️ @cpp_geek
Бинарный поиск

Чаще всего бинарный поиск (бинпоиск) используют, чтобы найти элемент в отсортированном массиве. Мы начинаем искать с середины массива. Если находим то, что нужно, или если больше нечего рассматривать, мы останавливаемся. В противном случае мы решаем, в каком направлении — вправо или влево от середины — мы должны продолжить поиск. Так как пространство поиска после каждой проверки делится на два, то время выполнения алгоритма — O(log n).
➡️ @cpp_geek
Сложный расчет констант

Использование констант – хороший тон. Это позволяет компилятору лучше оптимизировать код и делает его более явным. Но если вычисление слишком громоздкое, от модификатора const приходится отказываться. На помощь приходят лямбда-функции.
➡️ @cpp_geek
Упрощаем дебаг

Определите оператор << для структур STL, чтобы упростить добавление отладочных выходов в ваш код. Это лучше, чем стандартные функции вывода. Также определите соответствующий макрос.
➡️ @cpp_geek
Трюки с логарифмом

Функцию log тоже можно использовать для ряда изящных решений.
➡️ @cpp_geek
Новые атрибуты [[likely]] и[[unlikely]]

В C++20 мы получаем новые атрибуты [[likely]] и [[unlikely]], которые позволяют подсказывать оптимизатору, является ли путь выполнения более или менее вероятным.
➡️ @cpp_geek
Встроенные алгоритмы

Удобно использовать встроенные функции all_of, any_of и none_of для быстрой проверки элементов коллекции на соответствие условию.
➡️ @cpp_geek
Строковые литералы как параметры шаблона

Начиная с C ++ 20, вы можете использовать строку в качестве параметра шаблона, не являющегося типом. Идея состоит в том, чтобы использовать стандартную строку basic_fixed_string, которая имеет конструктор constexpr. Конструктор constexpr позволяет ему создать экземпляр фиксированной строки во время компиляции.

Вроде бы мелочь, а приятно — не нужно производить обходных маневров и использовать лишнюю память.
➡️ @cpp_geek
Проверка специализации типа

Иногда встает задача проверить, является ли конкретный тип данных специализацией определенного шаблона. Для этого можно использовать синтаксис шаблонов template.
➡️ @cpp_geek