Senior C++ Developer
12.2K subscribers
1.37K photos
3 videos
616 links
Изучаем C++.

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

РКН: https://www.gosuslugi.ru/snet/676e9a1e4e740947beca35ba
Download Telegram
nullptr

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

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

Это полезно, когда вы просто хотите получить элементы массива/контейнера или сделать с ними что-то, не заботясь об индексах, итераторах или кол-ве элементов.
Строго-типизированный enum

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

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

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

Эти приёмы не так полезны в повседневном программировании, но помогут козырнуть на собеседовании или соревнованиях.
Трюки с логарифмом

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

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

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

Когда шаблонный класс задан в виде template<class T, typename... Args>, бывает трудно понять, какие аргументы можно использовать. Метод is_constructible из библиотеки type_traits даёт неполный ответ: он показывает, существует ли конструктор под конкретные аргументы. Для более полной картины можно использовать еще один шаблон.
Вызов функции через кортеж

Креативное применение шаблонов, которое позволяет вызвать любую функцию, передав в неё параметры в виде кортежа.
Шаблон Voodoo

Вы можете настраивать шаблоны класса под конкретные значения или типы аргументов: так работает специализация шаблонов классов C++. Если это рекурсия, можно записывать базовые случаи, а затем определить общий шаблон как рекурсивную комбинацию этих случаев.

Больше интересного по ссылке.
Программирование на С++ и URI в коде

Вы можете поместить URI в свой код на C++, и компилятор не выдаст ошибку. Любой идентификатор, за которым следует двоеточие, становится меткой goto в С++. Все, что следует за двойным слешем, воспринимается как комментарий. Именно поэтому в приведенном выше коде http – это метка, а //google.com/ – комментарий. Но компилятор может выдать предупреждение, так как заданная метка не используется.
Автовыведение типа

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

Увидеть преимущества можно даже на примере стандартных типов STL.
This media is not supported in your browser
VIEW IN TELEGRAM
Дерево Фенвика

Довольно простая и быстрая, но совсем не очевидная в плане идеи и понимания структура данных. Позволяет находить сумму на префиксе и изменять отдельные элементы за O(log n). В следующем посте — реализация на C++.
Структура представлена в виде массива f, в котором f[i] – сумма всех элементов от F[i] до i. Функция F(x) связана с битовым представлением аргумента. Вкратце можно описать так: F(x) заменяет группу единичных битов, находящихся в конце числа (младших) на нули. Если x заканчивается на нулевой бит, то F(x) = x. В битовых операциях F(x) задаётся так: F(x) = x & (x + 1).

Нам понадобятся три функции: прибавление x к элементу с индексом i, получение суммы дерева от 0до xи получение суммы на [a..b].
Объявление классов и функций

В init части цикла for можно объявлять не одни лишь переменные. Здесь также можно разместить классы и функции.

Благодаря этому можно использовать множество переменных с разными типами.
Объединения тоже могут быть шаблонами

Еще одна вещь, о которой знают немногие, это то, что объединения тоже могут быть шаблонами.

У них также могут быть конструкторы и функции-члены. Ничего общего с наследованием (включая виртуальные функции).
Что выведет код сверху?
Anonymous Quiz
9%
10 45.6 37
41%
104637
21%
1045.637
22%
10450
7%
Не знаю
Неиспользуемые переменные

Подобный макрос есть, например, в cocos2d-x, там он называется CC_UNUSED_PARAM. Из недостатков: теоретически, он может работать не на всех компиляторах. Тем не менее, в cocos2d-x он для всех платформ определен абсолютно одинаково.

Для чего? Этот макрос позволяет избежать предупреждения о неиспользуемой переменной, а читающему код он как бы говорит: «тот кто писал это — знал, что переменная не используется, все в порядке».
Бесконечный цикл

Для
чего? Когда while(true), while(1), for(;;) и прочие стандартные пути создания цикла кажутся не слишком информативными, можно использовать подобный макрос. Единственный плюс который он дает — чуть лучшую читаемость кода.