Jump to content

С++14

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

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

Новые возможности языка

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

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

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

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

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

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

auto DeduceReturnType();   // Return type to be determined.

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

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

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

auto Correct(int i)
{
  if (i == 1)
    return i;             // return type deduced as int

  return Correct(i-1)+i;  // ok to call it now
}

auto Wrong(int i)
{
  if (i != 1)
    return Wrong(i-1)+i;  // Too soon to call this. No prior return statement.

  return i;               // return type deduced as int
}

Альтернативный тип вычета при декларировании

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

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

int   i;
int&& f();
auto          x3a = i;     // decltype(x3a) is int
decltype(i)   x3d = i;     // decltype(x3d) is int
auto          x4a = (i);   // decltype(x4a) is int
decltype((i)) x4d = (i);   // decltype(x4d) is int&
auto          x5a = f();   // decltype(x5a) is int
decltype(f()) x5d = f();   // decltype(x5d) is int&&

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

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

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

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

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

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

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

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

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

Переменные шаблоны

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

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

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

template<typename T>
constexpr T pi = T(3.141592653589793238462643383);

// Usual specialization rules apply:
template<>
constexpr const char* pi<const char*> = "pi";

Инициализация совокупного члена

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

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

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

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

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

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

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

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

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

auto integer_literal = 1'000'000;
auto floating_point_literal = 0.000'015'3;
auto binary_literal = 0b0100'1100'0110;
auto a_dozen_crores = 12'00'00'000;

Общие лямбды

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

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

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

Касательно auto вывод типа, общие лямбды следуют правилам вывода аргументов шаблона (которые похожи, но не идентичны во всех отношениях). [ нужны разъяснения ] ). Код выше эквивалентен этому: [ 12 ]

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

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

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

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

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

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

auto lambda = [value = 1] {return value;};

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

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

std::unique_ptr<int> ptr(new int(10));
auto lambda = [value = std::move(ptr)] {return *value;};

Атрибут [[deprecated]]

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

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

[[deprecated]] int f();

[[deprecated("g() is thread-unsafe. Use h() instead")]]
void g( int& x );

void h( int& x );

void test()
{
  int a = f(); // warning: 'f' is deprecated
  g(a); // warning: 'g' is deprecated: g() is thread-unsafe. Use h() instead
}

Новые возможности стандартной библиотеки

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

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

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

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

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

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

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

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

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

Стандартные пользовательские литералы

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

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

  • «s», для создания различных std::basic_string типы.
  • «ч», «мин», «с», «мс», «нас», «нс», для создания соответствующего std::chrono::duration временные интервалы.
  • "if", "i", "il", для создания соответствующего std::complex<float>, std::complex<double> и std::complex<long double> мнимые числа.
auto str = "hello world"s; // auto deduces string
auto dur = 60s;            // auto deduces chrono::seconds
auto z   = 1i;             // auto deduces complex<double>

Два литерала «s» не конфликтуют, так как строковый литерал работает только со строковыми литералами , а второй — только с числами. [ 18 ]

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

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

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

tuple<string, string, int> t("foo", "bar", 7);
int i = get<int>(t);        // i == 7
int j = get<2>(t);          // Same as before: j == 7
string s = get<string>(t);  // Compile-time error due to ambiguity

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

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

std::make_unique можно использовать как std::make_shared для std::unique_ptr объекты. [ 7 ]

std::integral_constant получил operator() перегрузка, чтобы вернуть постоянное значение. [ 16 ]

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

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

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

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

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

The std::quoted Манипулятор потокового ввода-вывода позволяет вставлять и извлекать строки со встроенными пробелами, помещая разделители (по умолчанию двойные кавычки) на выходе и удаляя их на входе, а также экранируя любые встроенные разделители. [ 23 ]

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

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

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

  1. ^ Саттер, Херб (18 августа 2014 г.), У нас есть C++14! , получено 18 августа 2014 г.
  2. ^ «ИСО/МЭК 14882:2014» . ИСО .
  3. ^ Перейти обратно: а б с д и Вонг, Майкл (30 апреля 2013 г.). «Взгляд с совещания по стандарту C++, апрель 2013 г., часть 1» . Кафе C/C++ . Проверено 27 января 2016 г.
  4. ^ Перейти обратно: а б с Меррилл, Джейсон (17 апреля 2013 г.). «N3638 Вычисление типа возвращаемого значения для обычных функций (Редакция 5)» . Проверено 14 июня 2013 г.
  5. ^ «Страница 10 из: Объяснение C++ auto и decltype» .
  6. ^ Смит, Ричард (18 апреля 2013 г.). «N3652 Ослабление ограничений на функции constexpr» .
  7. ^ Перейти обратно: а б с д Саттер, Херб (20 апреля 2013 г.). «Отчет о поездке: встреча ISO C++ весной 2013 г.» . isocpp.org . Проверено 14 июня 2013 г.
  8. ^ Дос Рейс, Габриэль (19 апреля 2013 г.). «Шаблоны переменных N3651 (версия 1)» (PDF) .
  9. ^ Вандевурде, Дэвид; Вотилайнен, Вилле (17 апреля 2013 г.). «Инициализаторы и агрегаты элементов N3653» .
  10. ^ «23479 — реализация двоичных констант с префиксом «0b» .
  11. ^ Кроул, Лоуренс; Смит, Ричард; Снайдер, Джефф; Вандевурде, Давид (25 сентября 2013 г.). «N3781 Одинарные кавычки как разделитель цифр» (PDF) .
  12. ^ Вали, Фейсал; Саттер, Херб; Абрахамс, Дэйв (19 апреля 2013 г.). «Общие (полиморфные) лямбда-выражения N3649 (редакция 3)» .
  13. ^ «Захват перемещения в Lambda» . Переполнение стека .
  14. ^ Вонг, Майкл (30 апреля 2013 г.). «Взгляд с совещания по стандарту C++, апрель 2013 г., часть 3» . Кафе C/C++ . Проверено 14 июня 2013 г.
  15. ^ Хиннант, Ховард; Воллманн, Детлеф; Бём, Ганс (19 апреля 2013 г.). «N3659 Совместная блокировка в C++ (версия 2)» .
  16. ^ Перейти обратно: а б с д Вонг, Майкл (26 апреля 2013 г.). «Взгляд с совещания по стандарту C++, апрель 2013 г., часть 2» . Кафе C/C++ . Проверено 14 июня 2013 г.
  17. ^ «N3657 Добавление поиска гетерогенного сравнения в ассоциативные контейнеры (версия 4)» . 19 марта 2013 г.
  18. ^ Соммерлад, Питер (18 апреля 2013 г.). «Определенные пользователем литералы N3642 для типов стандартных библиотек (часть 1 — версия 4)» (PDF) .
  19. ^ Спертус, Майк (19 апреля 2013 г.). «Формулировка N3670 для адресации кортежей по типу: редакция 2» .
  20. ^ Уэйкли, Джонатан (18 апреля 2013 г.). «N3658 Целочисленные последовательности времени компиляции» . Проверено 5 января 2016 г.
  21. ^ Ясскин, Джеффри (19 апреля 2013 г.). «Вспомогательная функция N3668 Exchange(), версия 3» . Проверено 5 января 2016 г.
  22. ^ Спертус, Майк; Палл, Аттила (19 апреля 2013 г.). «N3671 Повышение надежности немодифицирующих операций с последовательностями: Редакция 2» . Проверено 5 января 2016 г.
  23. ^ Дауэс, Беман (19 апреля 2013 г.). «Предложение библиотеки строк в кавычках N3654 (редакция 2)» . Проверено 5 января 2016 г.
  24. ^ «Поддержка C++ в Clang» . Проверено 28 мая 2016 г.
  25. ^ «Поддержка стандартов C++ в GCC» . Проверено 28 мая 2016 г.
  26. ^ «Соответствие стандартам C++ от Microsoft» . 7 марта 2017 года . Проверено 7 марта 2017 г.
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: f87d6894d20f6d2d1f4fdbbff3f73376__1716426780
URL1:https://arc.ask3.ru/arc/aa/f8/76/f87d6894d20f6d2d1f4fdbbff3f73376.html
Заголовок, (Title) документа по адресу, URL1:
C++14 - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)