Обновления C подборка изменений из трех стандартов языка

Обновления C++, внесенные стандартами C++11, C++14 и C++17. Большая подборка нововведений самого языка и изменений стандартной библиотеки.

Обновления C подборка изменений из трех стандартов языка

Обновления C++17

Вывод аргументов для шаблонов классов

Теперь аргументы шаблонов автоматически выводятся не только для функций, но и для классов.

Объявление not-type шаблонных параметров с помощью auto

Если тип объекта входит в список not-type template, он может быть использован в качестве аргумента шаблона с помощью auto .

Выражения свертки

Поддерживается два типа свертки шаблонных параметров:

  • Унарная – выражения вида (. op e) или (e or …) , где op – это оператор, а e – нераскрытая группа параметров.
  • Бинарная – выражения вида (e1 op … op e2) , где либо e1 , либо e2 (но не оба сразу) является нераскрытой группой параметров.

Новые правила вывода типа auto при фигурной инициализации

Изменился вывод auto при использовании универсального синтаксиса инициализации. Раньше для auto x < 3 >тип выводился как std::initializer_list<int> , сейчас выводится int .

Constexpr лямбды

Лямбды, выполняющиеся во время компиляции, с использованием constexpr .

Захват this в лямбдах

Ранее захват this в лямбдах происходил только по ссылке. В C++17 *this теперь делает копию текущего объекта.

inline переменные

Спецификатор inline может применяться как к переменным, так и к функциям.

Вложенные пространства имен

Используйте оператор разрешения пространств имен для создания вложенных определений.

Структурированные привязки

В обновления C++17 входит новый синтаксис для деструктурирующей инициализации вида auto[ x,y,z ] = expr , где тип expr – это кортежеподобный объект. Подробнее о привязках вы можете узнать здесь.

Условные операторы с инициализацией

Новые версии инструкций if и switch позволяют упростить шаблоны кода.

constexpr if

Позволяет выполнять if-конструкции во время компиляции.

Символьные литералы UTF-8

Начинаются с u8 и имеют тип char . Значение символьного литерала UTF-8 равно его ISO 10646 значению.

Прямая инициализация списка перечислений

Перечисления теперь могут быть инициализированы с использованием braced-синтаксиса.

Обновления библиотеки С++17

std::variant

Типобезопасный union . В любой момент времени содержит значение одного из своих альтернативных типов (или вообще не имеет значения).

std::optional

Необязательное значение. Может использоваться в функциях или условиях.

std::any

Типобезопасный контейнер для единственного значения любого типа.

std::string_view

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

std::invoke

Вызывает Callable объект ( std::function или std::bind ) с параметрами.

std::apply

Вызывает объект класса Callable с кортежем аргументов.

std::filesystem

Предоставляет стандартный способ управления файлами, каталогами и путями в файловой системе.
Пример копирования большого файла во временный путь:

std::byte

Обеспечивает стандартный способ представления данных в двоичном виде. В отличие от char или unsigned char доступны только побитовые операции.

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

Манипуляции с мапами и множествами

Перемещения элементов и слияние контейнеров без затрат на создание копий и выделение/освобождение памяти.

Перемещение элементов из одного мапа в другой:

Вставка целого множества:

Вставка элементов без контейнера:

Изменение ключа элемента в мапе:

Параллельные алгоритмы

Многие из алгоритмов STL начали поддерживать политики параллельного выполнения: seq (последовательное), par (параллельное) и par_unseq (параллельное неупорядоченное).

Обновления C подборка изменений из трех стандартов языка

Обновления C++14

Двоичные литералы

Удобный способ представления base-2 чисел с разделителем ‘ .

Обобщенные лямбда-выражения

C++14 теперь позволяет использовать спецификатор типа auto в списке параметров, создавая полиморфные лямбды.

Инициализация лямбда-захватов

Позволяет создавать лямбда-захваты, инициализированные произвольными выражениями при создании лямбды.

Теперь можно захватывать move-only типы по значению. В примере ниже p в списке захвата task2 – это новая переменная.

Имя, присвоенное захваченному значению, не обязательно должно совпадать с именем указанной переменной.

Определение типа возвращаемого значения

При использовании типа auto для возвращаемого значения в C++14, компилятор попытается вывести тип самостоятельно.

decltype(auto)

Спецификатор типа decltype(auto) выводит тип, как auto , но сохраняет ссылки и CV-квалификаторы.

Ослабление ограничений для constexpr функций

Обновления C++14 этот значительно расширили набор конструкций, допустимых в constexpr функциях: добавились if -операторы, множественные return , циклы и т.д.

Шаблоны переменных

C++14 позволяет шаблонизировать переменные.

Обновления библиотеки C++14

Пользовательские литералы

Новые пользовательские литералы для типов стандартной библиотеки chrono и basic_string .

Целочисленные последовательности

std::integer_sequence представляет последовательности целых чисел.

  • std::make_integer_sequence<T, N. > – создает последовательности 0, . N – 1 с типом T .
  • std::index_sequence_for – преобразует пакет параметров шаблона в целочисленную последовательность.

Преобразование массива в кортеж:

std::make_unique

std::make_unique рекомендуется использовать для создания экземпляров std::unique_ptr , так как эта функция позволяет:

  • избежать использования оператора new ;
  • предотвратить дублирование кода при указании базового типа, который должен содержать указатель;
  • обеспечить безопасность при исключениях.

Предположим, мы вызываем функцию foo следующим образом:

Поскольку мы выделили данные в куче в первой конструкции T , здесь происходит утечка. std::make_unique обеспечивает безопасность при выбросе исключений:

Обновления C подборка изменений из трех стандартов языка

Обновления C++11

Семантика перемещения

Семантика перемещения связана с оптимизацией производительности – возможностью перемещения объекта без больших затрат на копирование.

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

Перемещения также позволяют передавать объекты std::unique_ptr .

Ссылки rvalue

В C++11 появились новые ссылки rvalue с синтаксисом A&& .

Автоматическое определение типа со значениями lvalue и rvalue:

Шаблоны с переменным числом аргументов

Синтаксис . создает пакет параметров или расширяет его. Шаблон с хотя бы одним пакетом параметров называется вариативным шаблоном.

Списки инициализации

Массивоподобные контейнеры элементов, созданные с использованием braced-синтаксиса. Например, < 1, 2, 3 >создает последовательность целых чисел с типом std:: initializer_list<int> .

Статические утверждения

Утверждения, вычисляемые во время компиляции.

Переменные с типом auto выводятся компилятором в зависимости от типа их инициализатора.

Это существенно улучшает читаемость:

Функции также могут выводить возвращаемый тип с помощью auto .

Лямбда-выражения

Лямбда – это безымянные объекты функций, способные захватывать переменные в области видимости. У них есть список захвата (capture list):

  • [] – ничего не захватывает.
  • [ = ] – захват локальных объектов по значению.
  • [ & ] – захват локальных объектов по ссылке.
  • [this] – захват указателя this по значению.
  • [a, &b] – захват объекта a по значению, b – по ссылке.

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

decltype

decltype – оператор, возвращающий объявленный тип переданного ему выражения. CV-квалификаторы и ссылки сохраняются, если они являются частью выражения.

Псевдонимы шаблонов

Псевдонимы шаблонов семантически похожи на typedef , однако они легче читаются и совместимы с шаблонами.

nullptr

В C++11 появился новый тип null-указателя, предназначенный для замены макроса NULL языка C.

Строго типизированные перечисления

Типобезопасные перечисления, которые решают множество проблем с перечислениями в C, включая неявные преобразования, невозможность указать базовый тип, загрязнение области видимости.

Атрибуты

Атрибуты создают универсальный синтаксис над __attribute__(. ) , __declspec и т. п.

constexpr

Выражения, которые вычисляются во время компиляции. В константном выражении могут выполняться только несложные вычисления.

Константные выражения с классами:

Делегирование конструкторов

Конструкторы теперь могут вызывать другие конструкторы в том же классе с помощью списка инициализаторов.

Пользовательские литералы

Пользовательские литералы позволяют расширить язык и добавить собственный синтаксис.

Преобразование Цельсия в градусы Фаренгейта:

Конвертация строки в целое число:

Явные замещения виртуальных функций

Указывает, что виртуальная функция переопределяет другую виртуальную функцию.

Спецификатор final

Указывает, что виртуальная функция не может быть переопределена в производном классе или, что класс не может быть от нее унаследован.

Функции по умолчанию

Обновления C++11 вводят более элегантный и эффективный способ обеспечить реализацию функции по умолчанию, например конструктора.

Удаленные функции

Более элегантный и эффективный способ обеспечить удаленную реализацию функции. Полезно для предотвращения копирования объектов.

For-циклы по коллекциям

Синтаксический сахар для перебора элементов контейнера (range-based for).

Обратите внимание на разницу при использовании int , а не int& :

Специальные функции семантики перемещения

С введением семантики перемещения в C++11 теперь есть конструктор перемещения и перемещающий оператор присваивания.

Преобразование конструкторов

Преобразует braced list в аргументы конструктора.

Явные функции преобразования

Функции преобразования теперь можно сделать явными с помощью спецификатора explicit.

Встроенные пространства имен

Все члены встроенного пространства имен обрабатываются так, как если бы они были частью родительского пространства имен.

Инициализаторы нестатических членов-данных

Позволяет инициализировать нестатические члены-данных там, где они объявлены.

Правые угловые скобки

Теперь необязательно добавлять пробелы между закрывающими угловыми скобками.

Обновления библиотеки C++11

std::move

Указывает, что переданный объект может быть перемещен из одного объекта в другой без копирования.

Выполнение перемещения – это просто приведение аргумента к rvalue:

std::forward

Может принимать на вход lvalue или rvalue и возвращать их как есть, без изменений, включает cv-квалификацию:

  • Т& & становится Т& ;
  • Т& && становится Т& ;
  • Т&& & становится Т& ;
  • T&& && становится T&& ;

Пример функции wrapper , которая просто пересылает другие A объекты в новый конструктор копирования или перемещения объекта A :

std::thread

Библиотека std::thread предоставляет стандартный способ управления потоками.

std::to_string

Преобразует числовой аргумент в строку std::string .

Признаки типа

Признаки типа определяет интерфейс на основе шаблона времени компиляции для запроса или изменения свойств типов.

Умные указатели

В обновления C++11 входят новые умные указатели: std::unique_ptr , std::shared_ptr , std::weak_ptr .

std:: chrono

Библиотека chrono содержит набор служебных функций и типов, которые имеют дело с длительностью, часами и временными точками.

Кортежи

Кортежи представляют собой наборы неоднородных значений фиксированного размера.

std::tie

Создает кортеж lvalue-элементов. Полезно для распаковки объектов std::pair и std::tuple .

std::array

std::array – это контейнер, построенный поверх C-подобных массивов. Поддерживает общие контейнерные операции, такие как сортировка.

Неупорядоченные контейнеры

Поддерживают среднюю постоянную сложность операций поиска, вставки и удаления. Есть четыре типа неупорядоченных контейнеров: unordered_set , unordered_multiset , unordered_map , unordered_multimap .

std::make_shared

std::make_shared рекомендуется использовать для создания экземпляров std::shared_ptr , так как эта функция позволяет:

  • избежать использования оператора new ;
  • предотвратить дублирование кода при указании базового типа, который должен содержать указатель;
  • обеспечить безопасность при исключениях;
  • предотвратить повторное выделение памяти.

Модель памяти

C++11 стандартизирует модель памяти языка, обеспечивая поддержку библиотек для потоковых и атомарных операций.

Обновления C++: подборка изменений из трех стандартов языка

Шпаргалки

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

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