C ++ 14

редактировать

C ++ 14 - это версия стандарта ISO / IEC 14882 для языка программирования C ++. Он задуман как небольшое расширение по сравнению с C ++ 11, включающее в себя в основном исправления ошибок и небольшие улучшения. Об одобрении было объявлено 18 августа 2014 года. C ++ 14 был выпущен 15 декабря 2014 года.

Поскольку более ранние версии стандарта C ++ были заметно запоздалыми, название «C ++ 1y» иногда использовалось до тех пор, пока его одобрение, аналогично тому, как стандарт C ++ 11 раньше назывался «C ++ 0x» с ожиданием его выпуска до 2010 года (хотя на самом деле он переместился в 2010 и, наконец, в 2011).

Содержание

  • 1 Новые возможности языка
    • 1.1 Вычисление типа возвращаемого значения функции
    • 1.2 Выведение альтернативного типа при объявлении
    • 1.3 Ослабленные ограничения constexpr
    • 1.4 Шаблоны переменных
    • 1.5 Агрегированная инициализация члена
    • 1.6 Двоичные литералы
    • 1.7 Разделители цифр
    • 1.8 Общие лямбда-выражения
    • 1.9 Лямбда-выражения
    • 1.10 Атрибут [[устаревший]]
  • 2 Новые возможности стандартной библиотеки
    • 2.1 Общие мьютексы и блокировка
    • 2.2 Неоднородный поиск в ассоциативных контейнерах
    • 2.3 Стандартные определяемые пользователем литералы
    • 2.4 Адресация кортежей через тип
    • 2.5 Меньшие возможности библиотеки
  • 3 Поддержка компилятора
  • 4 Ссылки
  • 5 Внешние ссылки

Новые языковые функции

Это функции, добавленные в основной язык C ++ 14.

Вывод типа возвращаемого значения функцией

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

Чтобы вызвать вывод типа возвращаемого значения, функция должна быть объявлена ​​с autoв качестве возвращаемого типа, но без конечного спецификатора возвращаемого типа в C ++ 11:

auto DeduceReturnType (); // Тип возвращаемого значения подлежит определению.

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

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

Рекурсия может использоваться с функцией этого типа, но рекурсивный вызов должен происходить после хотя бы одного оператора возврата в определении функции:

auto Correct (int i) {if (i = = 1) return i; // возвращаемый тип определяется как int return Correct (i-1) + i; // сейчас можно вызвать} auto Wrong (int i) {if (i! = 1) return Wrong (i-1) + i; // Слишком рано называть это. Нет предварительного заявления о возврате. вернуть я; // возвращаемый тип выводится как int}

Вывод альтернативного типа при объявлении

В C ++ 11 были добавлены два метода вывода типа. auto- это способ создать переменную соответствующего типа на основе заданного выражения. decltypeбыл способом вычислить тип данного выражения. Однако decltypeи autoвыводят типы по-разному. В частности, autoвсегда выводит не ссылочный тип, как если бы при использовании std :: decay, тогда как autoвсегда выводил ссылочный тип. Однако decltypeможно заставить вывести ссылочный или не ссылочный тип в зависимости от категории значения выражения и природы выражения, которое он выводит:

int i; int f (); авто x3a = i; // decltype (x3a) равен int decltype (i) x3d = i; // decltype (x3d) равно int auto x4a = (i); // decltype (x4a) is int decltype ((i)) x4d = (i); // decltype (x4d) равно int auto x5a = f (); // decltype (x5a) равен int decltype (f ()) x5d = f (); // decltype (x5d) is int

В C ++ 14 добавлен синтаксис decltype (auto). Это позволяет объявлениям autoиспользовать правила decltypeдля данного выражения.

Синтаксис decltype (auto)также можно использовать с выводом типа возвращаемого значения, используя синтаксис decltype (auto)вместо autoдля вывода типа возвращаемого значения.

Ослабленные ограничения constexpr

В C ++ 11 введена концепция функции, объявленной constexpr; функция, которая может быть выполнена во время компиляции. Их возвращаемые значения могут использоваться операциями, требующими постоянных выражений, таких как целочисленный аргумент шаблона. Однако функции constexpr C ++ 11 могут содержать только одно возвращаемое выражение (а также static_asserts и небольшое количество других объявлений).

C ++ 14 снимает эти ограничения. Функции, объявленные Constexpr, теперь могут содержать следующее:

  • Любые объявления, за исключением:
    • staticили thread_localпеременных.
    • Объявления переменных без инициализаторов.
  • Условные операторы ветвления ifи switch.
  • Любые операторы цикла, включая основанные на диапазоне для.
  • Выражения, которые изменяют значение объекта, если время жизни этого объекта началось в пределах константы функция выражения. Сюда входят вызовы любых нестатических функций-членов, не объявленных constconstexpr. Операторы

gotoзапрещены в C ++ 14 расслабленных функциях, объявленных constexpr.

Кроме того, C ++ 11 заявил, что все нестатические функции-члены, которые были объявлены constexpr, также были неявно объявлены constпо отношению к this. С тех пор это было удалено; нестатические функции-члены могут быть не- const. Однако в соответствии с указанными выше ограничениями функция-член, отличная от constconstexpr, может изменять член класса только в том случае, если время жизни этого объекта началось в пределах вычисления константного выражения.

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

В предыдущих версиях C ++ можно было создавать шаблоны только функций, классов или псевдонимов типов. C ++ 14 позволяет создавать переменные по шаблону. Примером, приведенным в предложении, является переменная pi, которую можно прочитать для получения значения pi для различных типов (например, 3при чтении как интеграл тип; ближайшее возможное значение с точностью float, doubleили long doubleпри чтении как float, doubleили long doubleсоответственно и т. д.).

К таким объявлениям и определениям применяются обычные правила шаблонов, включая специализацию.

шаблон constexpr T pi = T (3.141592653589793238462643383); // Применяются обычные правила специализации: шаблон <>constexpr const char * pi = "pi";

Агрегированная инициализация члена

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

C ++ 14 ослабляет это ограничение, разрешая агрегированную инициализацию для таких типов. Если список инициализации в фигурных скобках не предоставляет значение для этого аргумента, инициализатор элемента позаботится об этом.

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

Числовые литералы в C ++ 14 могут быть указаны в двоичная форма. В синтаксисе используются префиксы 0bили 0B. Синтаксис также используется в других языках, например. Java, C#, Swift, Go, Scala, Ruby, Python, OCaml, а также как неофициальное расширение в некоторых компиляторах C с не менее 2007 года.

Разделители цифр

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

auto integer_literal = 1'000'000;. auto float_point_literal = 0,000'015'3;. auto binary_literal = 0b0100'1100 '0110;. auto a_dozen_ crores = 12'00'00'000;. auto silly_example = 1'0'0'000'00;

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

В C ++ 11 параметры лямбда-функции должны быть объявлены с конкретными типами. C ++ 14 смягчает это требование, позволяя объявлять параметры лямбда-функции с помощью спецификатора типа auto.

auto lambda = (auto x, auto y) {return x + y;};

Что касается вывода типа auto, общие лямбда-выражения следуют правилам вывода аргументов шаблона (которые похожи, но не идентичны во всех отношениях). Приведенный выше код эквивалентен следующему:

struct {template auto operator () (T x, U y) const {return x + y;}} lambda {};

Общие лямбды - это, по сути, шаблонные лямбды-функторы.

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

Лямбда-функции C ++ 11 захватывают переменные, объявленные во внешней области видимости, путем копирования значения или по ссылке. Это означает, что члены-значения лямбды не могут быть типами, предназначенными только для перемещения. C ++ 14 позволяет инициализировать захваченные члены произвольными выражениями. Это позволяет как захват с помощью перемещения значения, так и объявление произвольных членов лямбда-выражения без наличия соответствующей именованной переменной во внешней области.

Это делается с помощью выражения инициализатора:

auto lambda = [значение = 1] {возвращаемое значение;};

Лямбда-функция lambdaвозвращает 1, то есть то, чем было инициализировано значение. Объявленный захват выводит тип из выражения инициализатора, как если бы с помощью auto.

Это можно использовать для захвата перемещением с помощью стандартной функции std :: move:

std :: unique_ptr ptr (новый int (10)); авто лямбда = [значение = std :: move (ptr)] {return * value;};

Атрибут [[deprecated provided sizes

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

[[не рекомендуется]] int f (); [[устарело ("g () небезопасно для потоков. Используйте вместо него h ()")]] void g (int x); void h (int x); void test () {int = f (); // предупреждение: 'f' устарела g (a); // предупреждение: 'g' устарела: g () небезопасна для потоков. Вместо этого используйте h ()}

Новые функции стандартной библиотеки

Общие мьютексы и блокировка

В C ++ 14 добавлен общий синхронизированный мьютекс и сопутствующий общий тип блокировки.

Гетерогенный поиск в ассоциативных контейнерах

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

C ++ 14 позволяет выполнять поиск по произвольному типу, если оператор сравнения может сравнивать этот тип с фактическим типом ключа. Это позволит сопоставить std :: stringс некоторым значением для сравнения с const char *или любым другим типом, для которого доступна перегрузка operator <.. Это также полезно для индексации составных объектов в std :: setпо значению одного члена, не заставляя пользователя findсоздавать фиктивный объект (например, создание всего struct Person, чтобы найти человека по имени).

Для сохранения обратной совместимости гетерогенный поиск разрешен только тогда, когда компаратор, присвоенный ассоциативному контейнеру, позволяет это. Классы стандартных библиотек std::less<>и std::greater<>расширены, чтобы разрешить гетерогенный поиск.

Стандартные определяемые пользователем литералы

C ++ 11 определил синтаксис для определяемых пользователем буквальных суффиксов, но стандартная библиотека не использовала ни один из них. В C ++ 14 добавлены следующие стандартные литералы:

  • "s" для создания различных типов std::basic_string.
  • "h", "min", "s", "ms", "us", "ns" для создания соответствующих временных интервалов std :: chrono :: duration.
  • "if", "i", "il", для создания соответствующих мнимых чисел std::complex, std::complexи std::complex.
auto str = "hello world "s; // автоматически выводит строку auto dur = 60s; // автоматически выводит хроно :: секунды auto z = 1i; // автоматически выводит комплексный 

Два литерала "s" не взаимодействуют, так как строковый один работает только с строковыми литералами, а второй - только с числами.

Адресация кортежей через тип

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

tuple t ("foo", "bar", 7); int я = получить (т); // i == 7 int j = get (t); // То же, что и раньше: j == 7 string s = get (t); // Ошибка времени компиляции из-за двусмысленности

Меньшие возможности библиотеки

std :: make_uniqueмогут использоваться как std :: make_sharedдля std :: unique_ptrобъекты.

std :: integration_constantполучил перегрузку operator ()для возврата постоянного значения.

Шаблон класса std :: integer_sequenceи связанные шаблоны псевдонимов были добавлены для представления целочисленных последовательностей времени компиляции, таких как индексы элементов в пакете параметров.

Глобальный std :: begin/ std :: end Функциибыли дополнены функциями std :: cbegin/ std :: cend, которые возвращают постоянные итераторы, и std :: rbegin/ std :: rendи std :: crbegin/ std :: crend ​​, которые возвращают обратные итераторы.

Шаблон функции std :: exchangeприсваивает новое значение переменной и возвращает старое значение.

Новые перегрузки std :: equal, std :: mismatchи std :: is_permutationпринимают пару итераторов для второго диапазона, так что вызывающей стороне не нужно отдельно проверять, что два диапазона имеют одинаковой длины.

Признак типа std :: is_finalопределяет, помечен ли класс как final.

Поток std :: quotedI / Манипулятор O позволяет вставлять и извлекать строки со встроенными пробелами, помещая разделители (по умолчанию в двойные кавычки) на выходе и удаляя их на входе, а также избегая любых встроенных разделителей.

Поддержка компилятора

Clang завершил поддержку C ++ 14 в 3.4, хотя и под стандартным именем c ++ 1y, и сделал C ++ 14 стандартом C ++ по умолчанию в Clang 6. GCC завершил поддержку C ++ 14 в GCC 5 и сделал C ++ 14 стандартом C ++ по умолчанию в GCC 6. Microsoft Visual Studio 2017 реализовала "почти все возможности C ++ 14.

Ссылки

Внешние ссылки

Последняя правка сделана 2021-05-13 08:52:44
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте