- PVSM.RU - https://www.pvsm.ru -
До C++20 осталась пара лет, а значит, не за горами feature freeze. В скором времени международный комитет сосредоточится на причёсывании черновика C++20, а нововведения будут добавляться уже в C++23.
Ноябрьская встреча в Сан-Диего — предпоследняя перед feature freeze. Какие новинки появятся в C++20, что из крупных вещей приняли, а что отклонили — всё это ждёт вас под катом.

Добавили новый тип данных char8_t. Массив этих символов представляет собой UTF-8 строку:
std::u8string hello = u8"Привет, мир!";
// TODO: Вывести значение пока нельзя!
//std::cout << hello;
На первый взгляд кажется, что нововведение незначительное. Но это не так.
char8_t — первый шаг к тому, чтобы стандартная библиотека C++ из коробки поддерживала UTF-8. Впереди ещё много работы, к C++20 она явно не завершится.
Однако уже теперь char8_t многим превосходит char/unsigned char. Программы, использующие char8_t, могут работать быстрее за счёт того, что char8_t не алиасится [1] с другими типами данных. Иными словами, модификация строки или любой переменной не приведёт к тому, что значения переменных будут перечитываться из памяти:
bool do_something(std::u8string_view data, int& result) {
result += data[0] - u8'0'; // переменная result изменилась
return data[0] != u8'0'; // будет использовано значение из регистра для data[0]
}
Если бы мы в примере взяли char (std::string_view), то получили бы код, в котором несколько раз обращаемся к BYTE PTR [rsi] [2]. В случае char8_t это не происходит [3].
Полный список изменений связанных с char8_t доступен в документе P0482 [4].
К C++20 многие (и я в их числе) хотят увидеть в стандарте контейнеры, которыми можно пользоваться на этапе компиляции. Это позволит делать меньше вычислений на runtime, а значит, при работе приложения будет тратиться меньше процессорного времени. При этом, зачастую, вам не придётся ничего менять в исходниках — всё просто начнёт работать быстрее, инициализироваться на этапе компиляции, лучше оптимизироваться компилятором…
В Сан-Диего сильно расширили возможности компилятора и стандартной библиотеки по вычислению выражений на этапе компиляции:
На следующем заседании, которое пройдёт в США 18–23 февраля 2019 года, планируется добавить контейнерам std::string, std::vector (и возможно std::map) возможность работать на этапе компиляции.
Все добавления и правки жизненно важны для готовящейся к C++23/26 рефлексии.
Начиная с C++20 можно будет дополнительно настраивать unordered контейнеры и обязывать их не конструировать временные объекты при операциях поиска:
struct string_hash {
// Без следующей строчки будут создаваться временные объекты!
using transparent_key_equal = std::equal_to<>;
size_t operator()(std::string_view txt) const { return std::hash<string_view>{}(txt); }
};
using unordered_set_string = std::unordered_set<std::string, string_hash, std::equal_to<> >;
template <class Value>
using unordered_map_string
= std::unordered_map<std::string, Value, string_hash, std::equal_to<> >;
// ...
unordered_map_string<int> map = { /* ... */};
assert(map.contains("This does not create a temporary std::string object :-)"));
Вещь весьма полезная, детали можно найти в документе P0919 [13].
Уже давно считается, что std::bind — достаточно опасная вещь, из-за которой легко пораниться. Поэтому в C++20 добавили более простую функцию std::bind_front.
Она не поддерживает placeholders, правильно работает с ref-qualifiers и компилируется немного быстрее. Пользоваться ей можно будет приблизительно вот так:
int foo(int arg1, std::string arg2, std::vector<int>&&, std::string_view);
// ...
auto bound = std::bind_front(foo, 42, "hello");
// ..
int result = bound(std::vector{42, 314, 15}, "word");
Всеобъемлющее описание есть в документе P0356 [14].
Ура, теперь можно подсказывать компилятору, что данные у нас выравнены:
void add(span<float> x, float addition) {
const auto size = x.size();
float* ax = std::assume_aligned<64>(x.data());
for (int i = 0; i < size; ++i)
ax[i] += factor;
}
Это поможет компилятору автоматически векторизовать циклы и генерировать более производительный код. Дополнительные примеры можно найти в документе P1007 [15].
В P1141 [16] приняли сокращённый синтаксис для записи шаблонных функций и классов, аргументы которых должны соответствовать концепту. Например, void sort(Sortable auto& c); значит, что sort — это шаблонная функция, и что тип переменной `c` соответствует концепту Sortable.
Классы std::optional и std::variant теперь обязаны иметь тривиальные деструкторы, copy/move конструкторы и copy/move операторы присваивания, если шаблонные параметры классов обладают свойствами тривиальности. Это немного поможет компилятору и стандартной библиотеке генерировать более производительный и компактный код (P0602 [17]).
Move-конструктор std::function теперь обязан быть noexcept. Если у вас есть std::vector<std::function> и конструкторы std::function раньше не были noexcept, то работа с таким вектором станет в несколько раз производительнее (P0771 [18]).
Если вы имели дело с большими массивами чисел и иcпользовали make_unique/make_shared, то иногда производительность слегка проседала за счёт того, что каждый элемент массива инициализировался нулём. Некоторые специально писали new T[x], чтобы не инициализировать каждое значение. Так вот, в C++20 добавили std::make_unique_default_init и std::make_shared_default_init. Эти две функции приехали из Boost и они не делают лишней инициализации (P1020 [19]).
Ещё добавили *_pointer_cast функции, принимающие rvalue. Это помогает избегать лишних инкрементов и декрементов атомарного счётчика при работе с std::shared_ptr (P1224 [20]).
В великолепном документе P0608 [21] убрали боль при использовании std::variant:
std::variant<std::string, bool> x = "abc"; // Ой! До C++20 `x` содержит `true`
Ещё один великолепный документ P0487 [22] того же автора избавляет от граблей, на которые очень многие наступали:
char buffer[64];
std::cin >> buffer; // Теперь гарантированно не переполняется
char* p = get_some_ptr();
std::cin >> p; // Теперь просто не компилируется
Наконец, решили, что в контрактах автор класса имеет право использовать приватные члены класса в условиях контракта (P1289 [23]):
struct int_reference {
// ...
int get() const [[expects: ptr_ != nullptr ]] { return *ptr_; }
private:
int* ptr_;
};
Итак, приступим к крупным нововведениям. И начнём с плохого: в C++20 нам не видать работы с сетью из коробки. Отложили на неопределённый срок.
К хорошим новостям — подгруппа EWG одобрила дизайн модулей, так что есть все шансы увидеть их в C++20. Финальная битва за модули предстоит на следующем заседании.
Ближайшие года уйдут у разработчиков языка C++ на оптимизации компиляторов для работы с модулями и на оптимизацию представления модуля.
Так же, стоит заметить, что для идеальной скорости сборки скорее всего понадобится дорабатывать вашу кодовую базу и размечать публичные и приватные интерфейсы экспорты модуля.
Ranges в C++20 приняли. На голосовании в последний день авторы предложения P0896 [24] сорвали долгие овации. Весь зал аплодировал стоя. Начало оваций даже успели сфотографировать, счастливый автор предложения — в шапке этого поста.
Вот пара примеров того, что можно делать с ranges:
#include <algorithm>
std::ranges::sort(some_vector);
std::ranges::find(email.c_str(), std::unreachable_sentinel, '@');
std::ranges::fill(std::counted_iterator(char_ptr, 42), std::default_sentinel, '!');
Возвращаемся к тому, что не приняли. Coroutines не вошли в стандарт на голосовании. Возможно, это случится на следующем заседании, но шансов маловато.
Хорошо это или плохо, подоспеет ли прототип к следующему заседанию — это открытые вопросы.
Предложение о двухмерной графике воскресили, над ним продолжают работать. Автор планирует закинуть прототип в общедоступное место (например, в Boost), обкатать, собрать отзывы экспертов по 2D графике из другого комитета по стандартизации.
На заседании мы в основном дотаскивали stacktrace (который мы в Яндекс.Такси очень любим) до стандарта C++. Сейчас черновик документа выглядит вот так [25]. Надеюсь, что осталось совсем чуть-чуть, и к C++20 успеем.
Ещё мы пытались привнести в стандарт плагины (динамическую загрузку библиотек, идея с stdcpp.ru [26]). Тут нас ждал провал — предложение отклонили. Учтём ошибки и попробуем позже.
Наше старое предложение добавить атрибут [[visible]] для упрощения создания динамических библиотек [27], внезапно подхватил другой разработчик в документе P1283 [28]. Всячески поддерживали документ на голосованиях, первую подгруппу прошли, надеемся на успех.
Идею упростить работу с std::variant, а именно «Добавить операторы сравнения std::variant с его элементами» [29], так же отклонили. Основные возражения — пока боязно менять std::variant, учитывая его проблемы с конструкторами (хотя после P0608 [21]) они исчезнут. Попробуем ещё раз.
С конкурентным unordered map (P0652 [30]) наоборот, всё было достаточно гладко: нам порекомендовали проверить пару альтернативных интерфейсов и сказали, что предложение почти готово для принятия в Concurrent Data Structures TS (правда, он пока только планируется).
В подгруппе SG6 Numerics мы прошлись по большинству имеющихся идей, предложили и немного обсудили механизм взаимодействия различных классов чисел (P0880 [31]). Ждём, когда начнут создавать Numbers TS, куда должны попасть все новые и вкусные классы чисел.
В подгруппе по ядру языка мы презентовали идеи о «Беспредельном copy elision» [32], а именно P0889 [33]. Люди очень хотят нечто подобное, но не в том виде, что было изложено. Нас отправили напрямую к разработчикам компиляторов за консультацией.
Ну и, как упоминалось выше, нашу бумагу Misc constexpr bits P1032 [11], приняли в C++20. Теперь можно будет использовать на этапе компиляции array, tuple, pair, всё что нужно для копировании std::string, back_insert_iterator, front_insert_iterator, insert_iterator.
C++20 обещает быть весьма занятным: Concepts, Contracts, Ranges, Modules, работа с временными зонами и множество constexpr нововведений.
В скором времени мы, Рабочая Группа 21, [34] отправим комментарии к черновику стандарта C++20. Поэтому, если у вас есть какая-то боль, или вы не согласны с каким-то нововведением, пожалуйста, оставляйте свои мысли на этой странице [35].
Также приглашаем вас на наши ближайшие встречи по C++: Открытая встреча РГ21 [36] в Москве и Санкт-Петербурге и C++ Siberia 2019 [37] в Новосибирске.
Автор: antoshkka
Источник [38]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/300465
Ссылки в тексте:
[1] не алиасится: https://en.wikipedia.org/wiki/Aliasing_(computing)
[2] в котором несколько раз обращаемся к BYTE PTR [rsi]: https://gcc.godbolt.org/z/pN4-n5
[3] это не происходит: https://gcc.godbolt.org/z/uw3Kg7
[4] P0482: https://wg21.link/p0482
[5] P1002: https://wg21.link/P1002
[6] P1327: https://wg21.link/P1327
[7] P1073: https://wg21.link/P1073
[8] P0595: https://wg21.link/P0595
[9] она очень своеобразна: https://godbolt.org/z/lqt1Cj
[10] P1330: https://wg21.link/P1330
[11] P1032: https://wg21.link/P1032
[12] P1006: https://wg21.link/P1006
[13] P0919: https://wg21.link/P0919
[14] P0356: https://wg21.link/P0356
[15] P1007: https://wg21.link/P1007
[16] P1141: https://wg21.link/P1141
[17] P0602: https://wg21.link/P0602
[18] P0771: https://wg21.link/P0771
[19] P1020: https://wg21.link/P1020
[20] P1224: https://wg21.link/P1224
[21] P0608: https://wg21.link/P0608
[22] P0487: https://wg21.link/P0487
[23] P1289: https://wg21.link/P1289
[24] P0896: https://wg21.link/P0896
[25] вот так: https://apolukhin.github.io/papers/d0881r3.html
[26] идея с stdcpp.ru: https://stdcpp.ru/proposals/b061944a-dc76-431d-ac57-5832978d63aa
[27] атрибут [[visible]] для упрощения создания динамических библиотек: https://stdcpp.ru/proposals/feb5244f-f6a9-4cc0-ae30-f6b549d2d6c9
[28] P1283: https://wg21.link/P1283
[29] «Добавить операторы сравнения std::variant с его элементами»: https://stdcpp.ru/proposals/c73a20b1-073e-463f-9f4e-c959de1ed072
[30] P0652: https://wg21.link/P0652
[31] P0880: https://wg21.link/P0880
[32] «Беспредельном copy elision»: https://stdcpp.ru/proposals/e6263404-2b60-49af-87c6-bd9bc1801257
[33] P0889: https://wg21.link/P0889
[34] мы, Рабочая Группа 21,: https://stdcpp.ru/about
[35] на этой странице: https://stdcpp.ru/proposals/e9e9e9f8-8844-4f46-91ff-e517c2b1d66e
[36] Открытая встреча РГ21: https://events.yandex.ru/events/cpp-party/04-dec-2018/
[37] C++ Siberia 2019: http://cpp-russia.ru/?page_id=1510
[38] Источник: https://habr.com/post/430406/?utm_campaign=430406
Нажмите здесь для печати.