- PVSM.RU - https://www.pvsm.ru -

C++20 всё ближе. Встреча в Джексонвилле

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

Хотите посмотреть на новости и узнать:
C++20 всё ближе. Встреча в Джексонвилле - 1

  • Почему это тут золотая медаль справа?
  • Как там поживает кросплатформенный SIMD?
  • Что будет если 4000 поделить на последнюю пятницу февраля?
  • Какие подводные камни нашлись у сопрограм?
  • Какие крутые фишки для многопоточного программирования будут в скором времени доступны?

Календари и временные зоны

Смотрите как красиво и легко теперь можно задавать даты в C++20:

using std::chrono;
year_month_day ymd = 2016y/May/29d; // 2016-05-29

Нужно работать ещё и с миллисекундами, да ещё и в часовом поясе Токио? Без проблем:

auto tp = sys_days{ymd} + 7h + 30min + 6s + 153ms; // 2016-05-29 07:30:06.153 UTC
zoned_time zt = {"Asia/Tokyo", tp};
cout << zt << 'n';                                          // 2016-05-29 16:30:06.153 JST

Есть инструменты для работы с международным атомным временем, разбором времён из строки, экзотические типы данных позволяющие хранить даты «вторая пятница февраля», «вторая неделя» или «вторая неделя марта». и т.п.

Так что теперь можно получить дату последней пятницы февраля 4000 года:

auto last_friday_feb = February/Friday[last];
std::cout << 4000 / last_friday_feb << std::endl;

Черновое описание всех возможностей доступно вот тут [1].

Span

Если вам нравится std::string_view из C++17 (или boost::string_view/boost::string_ref), то std::span вам тем более понравится!

Представьте себе, что у вас есть шаблонная функция, что-то делающая с массивом int:

void do_something(int* p, size_t size);

Чтобы вызвать этот метод нужно достаточно много писать:

std::vector<int> v;
do_something(v.data(), v.size());

int data[1024];
do_something(data, std::size(data));

boost::container::small_vector<int, 32> sm;
do_something(sm.data(), sm.size());

Другой минус — внутри такого метода неудобно работать с алгоритмами стандартной библиотеки + не будет работать range based for:

void do_something(int* p, size_t size) {
    std::sort(p, p + size);
    for (size_t i = 0; i < size; ++i) {
        p[i] += p[0];
    }
}

Так вот, std::span — это класс, который хранит указатель и размер массива данных (при том размер порой не хранится, а используется информация, доступная на этапе компиляции). С этим новым классом код становится несколько проще и без указателей:

void do_something(std::span<int> p) {
    std2::sort(p);
    for (int& v: p) {
        v += p[0];
    }
}
// ...
std::vector<int> v;
do_something(v);

int data[1024];
do_something(data);

boost::container::small_vector<int, 32> sm;
do_something(sm);

Описание std::span доступно в pdf [2].

typename? Забудьте о нём в C++20!

Если вы путались, когда надо ставить typename, а когда – не надо, то у меня для вас хорошие новости! Начиная с C++20 в подавляющем большинстве мест можно будет не писать typename:


template<class T> T::R f();

template<class T> struct S {
    using Ptr = PtrTraits<T>::Ptr;

    T::R f(T::P p) {
        return static_cast<T::R>(p);
    }

    auto g() -> S<T*>::Ptr;
};

Новые атрибуты

  • [[no_unique_address]] — если пометите этим аттрибутом переменную класса, то компилятор сможет более агрессивно оптимизировать её расположение в памяти. Например, может в принципе не выделять под неё место.
  • [[likely]] — помечаете им выражение (например `if (flag){ [[likely]] std::cout << «OK»; }` ) или case от switch, и компилятор начинает оптимизировать код, считая, что помеченная ветка будет выполняться чаще, чем другие.
  • [[unlikely]] — подсказывает компилятору, что в это место мы редко попадаем на рантайме.

Сonstexpr метапрограммирование

Внезапная прорывная новость – комитет предварительно одобрил бумагу о использовании std::allocator в constexpr выражениях. Предстоит ещё огромное количество работы, но оптимистичный прогноз – получить к C++20 std::vector и std::string, которые можно использовать в выражениях на этапе компиляции. Это позволит компиляторам лучше оптимизировать, позволит использовать привычные всем контейнеры для рефлексии, метапрограммирования и метаклассов.

Работа в этом направлении продвигается не так быстро, как хотелось бы. Но, тем не менее, на встрече окончательно одобрили бумагу от РГ21 [3] о добавлении «constexpr iterator» [4], что позволит требовать от контейнера итераторов, применимых на этапе компиляции. Другую нашу бумагу на constexpr тему [5] рассмотреть не успели.

Если кто еще не видел рассказ о метаклассах, рефлексии и людях, развивающих эти направления, то рекомендую посмотреть Herb Sutter “Meta: Thoughts on generative C++” [6].

Новые примитивы для многопоточности и векторных вычислений

Готовится к публикации «Parallelism 2 TS». Самыми интересными вещами, на мой взгляд, является тип данных для SIMD вычислений, благодаря которому можно писать оптимизированный кроссплатформенный код. В зависимости от платформы под капотом будет использоваться различный набор векторых инструкций (SSE, AVX, NEON, MDMX и т.п.):

void compute_on_aligned_data(float* data, size_t N) {
    size_t i = 0;
    for (; i + native_simd<float>::size() <= N; i += native_simd<float>::size()) {
        native_simd<float> v(data + i, vector_aligned);
        where(v > 100.f, v) = 100.f + (v - 100.f) * 0.1f;
        v.copy_to(data + i, vector_aligned);
    }

    for (; i < N; ++i) {
        float x = data[i];
        if (x > 100.f) {
            x = 100.f + (x - 100.f) * 0.1f;
        }
        data[i] = x;
    }
}

Подробности по SIMD доступны в черновике предложения [7].

Остальные новинки параллелизма (включая примитивы для fork based параллелизма, новые многопоточные алгоритмы, тип данных для сохранения набора одновременно возникших исключений и т.п.) доступны в черновике [8].

Прочее

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

Сопрограммы

Добавляли функциональность для симметричных сопрограм, просмотра параметров в promise. Длительное время обсуждали проблемы, на которые наталкивались пользователи сопрограм. Так, например, следующий достаточно невинный код ведёт к падению приложения:

future​<std::string>​ ​concat​(const​ std::string​& ​ prefix​, future​<std::string>​ suffix​) {
    co_return ​ (prefix ​ + ​ co_await suffix​);
}

Модули

Решали проблемы, возникающие при их имплементации. Упрощали их использование. Ничего прорывного, полёт нормальный.

Reflection TS

Начали формировать новый TS для рефлексии. В основе него пока что находится вот это предложение [9]. Выпущено в свет будет ещё не скоро.

Премия Дрейпера и Оскар

Помимо новостей, напрямую связанных с развитием языка C++, есть ещё новости на смежные темы.

Так Бьёрн Страуструп получил престижную премию Дрейпера [10] за развитие языка C++. На что Бьёрн сказал, что это заслуга всей WG21, и для всех участников закатил банкет.

К другим новостям. О C++ теперь знают актёры Голливуда. При получении Оскара создатель Houdini, популярной программы для графических эффектов, поблагодарил разработчиков языка C++ за C++11 [11].

Вместо итогов

Следующее собрание комитета будет летом. Если вы хотите что-то изменить в C++ или предложить свою идею, то всегда можете написать на https://stdcpp.ru/ [3], где люди из РГ21 помогут вам донести ваши желания до комитета.

Желаете поговорить с нами вживую? Ищите нас на апрельской конференции C++ Russia [12] в Питере.

Хотите пообсуждать C++ с другими разработчиками? К вашим услугам телеграм чат для новичков [13] и чат для матёрых разработчиков [14], знающих разницу между memory_order_relaxed и memory_order_seq_cst.

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

Автор: antoshkka

Источник [15]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/algoritmy/275963

Ссылки в тексте:

[1] вот тут: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0355r4.html

[2] в pdf: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0122r6.pdf

[3] РГ21: https://stdcpp.ru/

[4] «constexpr iterator»: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0858r0.html

[5] на constexpr тему: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0879r0.html

[6] Herb Sutter “Meta: Thoughts on generative C++”: https://www.youtube.com/watch?v=4AfRAVcThyA

[7] в черновике предложения: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0214r8.pdf

[8] в черновике: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4725.html

[9] вот это предложение: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0194r5.html

[10] премию Дрейпера: https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B5%D0%BC%D0%B8%D1%8F_%D0%94%D1%80%D0%B5%D0%B9%D0%BF%D0%B5%D1%80%D0%B0

[11] поблагодарил разработчиков языка C++ за C++11: https://www.youtube.com/watch?v=vdaerPPHkLg&feature=youtu.be&t=162

[12] C++ Russia: http://cppconf.ru/

[13] для новичков: https://t.me/supapro

[14] чат для матёрых разработчиков: https://t.me/ProCxx

[15] Источник: https://habrahabr.ru/post/351492/?utm_campaign=351492