C ++ 14 - это версия стандарта ISO / IEC 14882 для языка программирования C ++. Он задуман как небольшое расширение по сравнению с C ++ 11, включающее в себя в основном исправления ошибок и небольшие улучшения. Об одобрении было объявлено 18 августа 2014 года. C ++ 14 был выпущен 15 декабря 2014 года.
Поскольку более ранние версии стандарта C ++ были заметно запоздалыми, название «C ++ 1y» иногда использовалось до тех пор, пока его одобрение, аналогично тому, как стандарт C ++ 11 раньше назывался «C ++ 0x» с ожиданием его выпуска до 2010 года (хотя на самом деле он переместился в 2010 и, наконец, в 2011).
Это функции, добавленные в основной язык 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
для вывода типа возвращаемого значения.
В C ++ 11 введена концепция функции, объявленной constexpr; функция, которая может быть выполнена во время компиляции. Их возвращаемые значения могут использоваться операциями, требующими постоянных выражений, таких как целочисленный аргумент шаблона. Однако функции constexpr C ++ 11 могут содержать только одно возвращаемое выражение (а также static_assert
s и небольшое количество других объявлений).
C ++ 14 снимает эти ограничения. Функции, объявленные Constexpr, теперь могут содержать следующее:
static
или thread_local
переменных.if
и switch
.для
.const
constexpr
. Операторыgoto
запрещены в C ++ 14 расслабленных функциях, объявленных constexpr.
Кроме того, C ++ 11 заявил, что все нестатические функции-члены, которые были объявлены constexpr
, также были неявно объявлены const
по отношению к this
. С тех пор это было удалено; нестатические функции-члены могут быть не- const
. Однако в соответствии с указанными выше ограничениями функция-член, отличная от const
constexpr
, может изменять член класса только в том случае, если время жизни этого объекта началось в пределах вычисления константного выражения.
В предыдущих версиях 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 {templateauto operator () (T x, U y) const {return x + y;}} lambda {};
Общие лямбды - это, по сути, шаблонные лямбды-функторы.
Лямбда-функции C ++ 11 захватывают переменные, объявленные во внешней области видимости, путем копирования значения или по ссылке. Это означает, что члены-значения лямбды не могут быть типами, предназначенными только для перемещения. C ++ 14 позволяет инициализировать захваченные члены произвольными выражениями. Это позволяет как захват с помощью перемещения значения, так и объявление произвольных членов лямбда-выражения без наличия соответствующей именованной переменной во внешней области.
Это делается с помощью выражения инициализатора:
auto lambda = [значение = 1] {возвращаемое значение;};
Лямбда-функция lambda
возвращает 1, то есть то, чем было инициализировано значение
. Объявленный захват выводит тип из выражения инициализатора, как если бы с помощью auto
.
Это можно использовать для захвата перемещением с помощью стандартной функции std :: move
:
std :: unique_ptrptr (новый 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 добавлены следующие стандартные литералы:
std::basic_string
.std :: chrono :: duration
.std::complex
, std::complex
и std::complex
.auto str = "hello world "s; // автоматически выводит строку auto dur = 60s; // автоматически выводит хроно :: секунды auto z = 1i; // автоматически выводит комплексный
Два литерала "s" не взаимодействуют, так как строковый один работает только с строковыми литералами, а второй - только с числами.
Тип std :: tuple
, представленный в C ++ 11, позволяет индексировать совокупность типизированных значений с помощью целого числа константы времени компиляции. C ++ 14 расширяет это, чтобы разрешить выборку из кортежа по типу, а не по индексу. Если в кортеже более одного элемента типа, возникает ошибка времени компиляции:
tuplet ("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 :: quoted
I / Манипулятор 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.