Pull to refresh

Дорога к С++20

Reading time6 min
Views33K
imageСегодня завершилась летняя встреча комитета ISO WG21 C++, проходившая в Торонто с 10 по 15 июля. Вскоре нас наверняка ждёт подробный отчёт от РГ21, а сегодня уважаемой публике предлагается пост-«разогрев» с обсуждением самого интересного.

Итоги встречи следующие: стандарт С++17 завершен и будет опубликован на следующем собрании в ноябре этого года; стандарт С++20 уже обзавелся первыми серьезными фичами — концептами (concepts), явными обобщёнными лямбда-функциями (explicit generic lambdas) — и это только начало.

Возможности нового стандарта С++17 обсуждались уже не раз, про нововведения писали на Хабре, проводили доклады на конференциях, поэтому снова их приводить здесь я не буду. Не секрет, что ключевой особенностью этого выпуска С++ стал перенос самых «вкусных» возможностей в неопределенное будущее. Что ж, теперь можно с уверенностью сказать, что многие долгожданные «фичи» переехали именно в С++20. Взятый курс на расширение stdlib никуда не делся, поэтому от C++20 можно ожидать гораздо большего и богатого набора функций.


Черновик стандарта С++20


Концепты


Многострадальные Concepts, когда-то не вошедшие в C++11, потом переделанные в виде нового предложения Concepts-Lite, наконец-то становятся частью стандарта.

По поводу краткого синтаксиса для концептов (terse syntax) комитету договориться пока не удалось; однако, обсуждение будет продолжаться в рамках С++20.

_VA_OPT_


#define LOG(msg, ...) printf(msg __VA_OPT__(,) __VA_ARGS__)

LOG("hello world")   // => printf("hello world")
LOG("hello world", ) // => printf("hello world")
LOG("hello %d", n)   // => printf("hello %d", n)


Явные обобщённые лямбда-функции (Explicit generic lambdas) [pdf]


[] <typename T> (T t) { /* ... */ }

Лямбда-функции были добавлены в язык в стандарте C++11, требовавшие указания конкретного типа; стандарт C++14 в свою очередь позволил объявлять параметры лямбда-функций со спецификатором типа auto:
[](auto x) { /* ... */ }

Теперь взаимодействовать с типами параметра (или параметров) станет проще — при определении лямбда-функций можно будет использовать привычный синтаксис шаблона функций:

[]<typename T>(T x) { /* ... */ }
[]<typename T>(T* p) { /* ... */ }
[]<typename T, int N>(T (&a)[N]) { /* ... */ }


shared_ptr для массивов [pdf]


shared_ptr<double[]> p = make_shared<double[]>(1024);

Тема поднималась неоднократно — например, здесь1.

Определение порядка байтов


Больше нет нужды прибегать к хитрым приёмам — на самом деле, компилятор и так всегда знал ответ, просто теперь он им сможет поделиться:
enum class endian
{
  little = __ORDER_LITTLE_ENDIAN__,
  big    = __ORDER_BIG_ENDIAN__,
  native = __BYTE_ORDER__
};


Назначенный инициализатор (designated initializer) [pdf]


struct A { int x; int y; int z; }; A b{.x = 1, .z = 2};


Инициализаторы битовых полей по умолчанию (default bit-field initializers)


struct S {int x : 8 = 42;};

Нововведение, которое ожидали еще со времен появления «in-class initialization» в C++11: теперь declarator для членов битового поля поддерживает инициализацию.

Исправлены const-qualified указатели на члены


struct X { void foo() const&; };
X{}.foo();        // this is okay
(X{}.*&X::foo)(); // ill-formed in C++17, well-formed in C++2a


Улучшенная дедукция аргумента шаблона


vector v{vector{1, 2}};
 // Выведет vector<int> вместо vector<vector<int>>


TS (Technical Specifications)



Перечисленные ниже TS отныне являются частью С++17 (уже обсуждались в прошлые разы):
  • Filesystem v1 [pdf] — порт boost::filesystem,
  • Parallelism v1 [pdf] — благодаря этому TS, большая часть библиотеки algorithm отныне будет доступна в «параллельной» версии,
  • Library Fundamentals v1 [pdf] — расширение стандартной библиотеки: std::string_view, std::optional, std::any, system_error.


Помимо этого, комитет опубликовал следующие технические спецификации, для которых компиляторы уже могут делать экспериментальные реализации (и они наверняка здесь обсуждались ранее):
  • Coroutines v1 — вокруг сопрограмм было много обсуждений
  • Ranges v1 — проскочили вслед за концептами, и, будем надеяться, попадут в С++20
  • Networking v1 — имеет все шансы попасть в C++20; библиотека для работы с сокетами, в основе которой лежит boost::asio.

Далее рассматриваются TS, работа над которыми все ещё продолжается.
Некоторые из них — но, определенно, не все — войдут в состав С++20.

Модули (Modules) [pdf]


Модули по-прежнему находятся в разработке, однако, в их жизни случилось серьезное событие — стал доступен ранний черновик TS Модулей. В его публичной версии за прошедшее время ничего не изменилось (не считая пары мелких деталей) — т.е. модули по-прежнему основываются на дизайне Microsoft и не экспортируют макросы. По этому вопросу хотелось бы услышать мнение членов комитета, поскольку есть подозрения, что это не окончательное решение.

Concurrency v1 [pdf]


Опубликован, собирались принимать на этой встрече, однако фичи на разной стадии готовности — так что уже на следующей встрече данный TS будет частично принят в С++20. Содержит улучшения, которые сделают futures неблокирующими (в отличие от std::async), а также latches, барьеры и atomic smart pointers atomic_shared_ptr. Не вошел в С++17 по причине того, что был поздно опубликован и не получилось собрать достаточно практического опыта.
Непосредственно имплементация была вдохновлена MS Visual Studio, HPX и just::thread. Перед встречей были опасения, что новые предложения P0676 и P0701 могут отодвинуть принятие TS на неопределенный срок.

Transactional Memory v1 [pdf]


Опубликован, однако по этому TS еще совсем недавно у его же авторов оставались вопросы по части того, насколько быстрыми могут быть атомики и shared_ptr вне транзакций, если они должны с транзакцией взаимодействовать. Остается ждать разъяснений по поводу того, изменилось ли что-либо с прошлого раза.

Library Fundamentals v2


Опубликован. Нечто вспомогательное, потребуется для С++20.

Executors v1 [pdf]


В разработке. Должен войти в С++20, т.к. на него завязаны несколько других TS библиотек, связанных с гетерогенными вычислениями.

Reflection v1 [pdf]


В разработке. Есть все шансы попадания в С++20, ибо ему будет посвящена одна из грядущих встреч.

В основе TS лежат интроспекция кода и (с недавних пор) материализация (reification). По мнению комитета, TS пригодится в метапрограммировании, ставшему популярным благодаря Boost::Hana и аналогичных библиотек — а также для гетерогенных контейнеров.

Concurrency v2


В разработке на ранней стадии. Библиотека concurrent data structures, сoncurrent queues, lock-free алгоритмов и структур данных; включает в себя Hazard pointers (указатели опасности), RCU (безопасное освобождение памяти для lock-free контейнеров), atomic views. Вероятность попадания в С++20 крайне мала, т.к. находится еще на ранней стадии — при этом комитет осознает востребованность этого функционала и он, по словам автора, в самой активной разработке.

Parallelism v2


В разработке. Оказывается, за время разработки Parallelism v1 сделали не только Parallel STL для CPU, но и для GPU. Parallelism v2 —

Library Fundamentals v3


В разработке.

Contracts v1


В разработке. Будет либо TS, либо включение в стандарт С++20. Вкратце: улучшенная версия assert, которая позволяет проводить проверку пре- и пост- условий (т.е. инварианты). По мнению комитета, библиотека поможет С++ стать более безопасным языком, чтобы разработчики ПО для медицины, автомобилей, авиации и кибер-безопасности спали спокойней.

Numerics [pdf]


В разработке на ранней стадии. Кое-что из продвинутой арифметики наверняка войдет в С++20: decimal floating point, bounded types (например, fixed point types), unbounded types, multiprecision arithmetic. Должно пригодиться в работе в работе игровым разработчикам (которые, впрочем, привыкли сами писать то, что им требуется).

2D Graphics v1


На ранней стадии.

По мелочи


Идёт работа над добавлением новых функций к std::string — starts_with, ends_with.

Стоит заметить, что причиной появления сразу нескольких будущих TS стали распределенные и гетерогенные вычисления. Участники комитета понимают, что вот уже долгое время CUDA/OpenMP/OpenCL обгоняет нативный C++. В данный момент, все функции вроде std::invoke, std::async, параллельные алгоритмы и пр. предполагают, что std::thread используется исключительно на CPU; и даже несмотря на то, что черновик Executors TS содержит подвижки на этом фронте в виде включения в него новых фич, этого будет недостаточно, и работы предстоит еще очень много.

Уже продолжительное время эксперты из Google, NVidia, Codeplay и NASDAQ принимают участие в работе над черновиками грядущих TS, чтобы определить направление развития С++, и приоритеты будущего языка вам известны: Concurrency, Parallelism, Transactional Memory, и Networking.

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

Литература


Как обычно, прошу прощения за любые допущенные неточности.
Michael Wong — What's in C++20 and the C++17 final score card
Обсуждение
2017 Toronto ISO C++ Committee Discussion Thread (Concepts in C++20; Coroutines, Ranges and Networking TSes published)
C++17: The Language Features — Nicolai Josuttis
Trip report: Summer ISO C++ standards meeting (Toronto)
Tags:
Hubs:
Total votes 50: ↑50 and ↓0+50
Comments193

Articles