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

Ещё один шажок к C++20. Встреча в Альбукерке

Из центральной части [1] Канады — на юго-запад США! Альбукерке расположен в штате Нью-Мексико:

Ещё один шажок к C++20. Встреча в Альбукерке - 1

На встрече международного комитета по стандартизации C++, которая прошла в этом городе, приняли одно очень большое нововведение в С++20 и несколько маленьких.

operator <=>

В черновик C++20 был добавлен оператор spaceship, с помощью которого можно за одну операцию определять отношение элементов. В простых случаях это значит, что можно определить оператор spaceship и ваш класс научится сравниваться любыми способами: <, >, <=, >=, == и !=. Пример:

Без оператора spaceship С оператором spaceship
struct point3d {
    int x;
    int y;
    int z;
};

using p_ref = const point3d&;

bool operator==(p_ref a, p_ref b) {
    return a.x == b.x
        && a.y == b.y
        && a.z == b.z
    ;
}
bool operator< (p_ref a, p_ref b) {
    return a.x < b.x
        || (a.x == b.x && a.y < b.y)
        || (a.x == b.x && a.y == b.y
            && a.z < b.z)
    ;
}

bool operator!=(p_ref a, p_ref b) {
    return !(a == b);
}
bool operator<=(p_ref a, p_ref b) {
    return !(b < a);
}
bool operator> (p_ref a, p_ref b) {
    return b < a;
}
bool operator>=(p_ref a, p_ref b) {
    return !(a < b);
}

struct point3d {
    int x;
    int y;
    int z;

    auto operator<=>(const point3d&)
        const = default;
};

Поведение оператора можно настраивать типом возвращаемого значения:

class weak_equality;
class strong_equality;
class partial_ordering;
class weak_ordering;
class strong_ordering;

Кроме того, можно писать тело самого оператора, если вам необходимо какое-то особое поведение:

#include <compare> // weak_ordering, is_neq

struct point3d {
    int x;
    int y;
    int z;

    std::weak_ordering operator<=>(const point3d& p) const {
        using std::abs;
        if (auto cmp = abs(z) <=> abs(p.z); std::is_neq(cmp)) return cmp;
        if (auto cmp = abs(x) <=> abs(p.x); std::is_neq(cmp)) return cmp;
        return abs(x) <=> abs(p.x);
    }
};

Описание поведения оператора и примеры использования можно найти в этом документе [2]. Интеграция spaceship со стандартной библиотекой описана здесь [3]*.

Особенно приятно видеть, что добавили следующий алгоритм:

lexicographical_compare_3way(InputIterator1 b1, InputIterator1 e1, InputIterator2 b2, InputIterator2 e2);

Теперь можно эффективно, в один проход, сравнивать диапазоны данных.

osyncstream

Многие из читателей наверняка писали в std::cout/std::cerr из нескольких потоков одновременно и видели странный вывод:

#include <iostream>
#include <thread>
#include <string_view>

void say_hello(std::string_view username) {
    std::cerr << "Hello " << username;
}

void beware_of(std::string_view something) {
    std::cerr << something << " is dangerous";
}

int main() {
    std::thread t1([]{
        say_hello("Rachel");
    });

    std::thread t2([]{
        beware_of("darkness");
    });

    std::cerr << 'n';
 
    t2.join();
    t1.join();

    /* Possible output:
            Hello darkness
            Rachel is dangerous
    */
}

Так вот, в C++20 добавили классы, которые позволяют легко и без лишних накладных расходов избежать перемешивания выводов:

#include <iostream>
#include <thread>
#include <string_view>

void say_hello(std::string_view username) {
    std::osyncstream{std::cerr} << "Hello " << username;
}

void beware_of(std::string_view something) {
    std::osyncstream(std::cerr) << something << " is dangerous";
}

int main() {
    std::thread t1([]{
        say_hello("Rachel");
    });

    std::thread t2([]{
        beware_of("darkness");
    });

    std::cerr << 'n';
 
    t2.join();
    t1.join();
}

Подробности — в этой бумаге [4]*.

Заслуги РГ21 [5]

Мы, как всегда, ездили на заседание с несколькими предложениями:

  • P0539R2 [6] — integers, размер (количество байт) которых задаётся на этапе компиляции. В интерфейсе решили использовать биты, посоветовали разбить бумагу на несколько бумаг поменьше, обсуждали исключения и причие мелочи. Нужно обновлять proposal.
  • P0415R0 [7]* — constexpr для std::complex. Приняли в C++20 и прямо на месте пометили ещё пару функций как constexpr.
  • P0202R2 [8]* — constexpr для большинства алгоритмов в <algorithm>. Бумагу разделили на две части и приняли в C++20 ту часть, в которой идёт речь об алгоритмах алгоритмы, не использующих std::swap. Оставшуюся часть примут на следующих заседаниях, будет отдельный proposal.
  • P0275R2 [9] — shared_library или классы, необходимые для динамической загрузки библиотек. Рассмотрели в группе Evolution, решили, что бумага затрагивает только стандартную библиотеку и допустимо оставить поведение плагинов не специфицированным. Дальнейшая работа будет происходить в группе Library Evolution на следующих заседаниях.
  • P0858R0 [10] (ещё не выложили в открытый доступ) — эту бумагу написали прямо во время встречи в Альбукерке. Бумага позволяет работать с итераторами std::basic_string_view и std::array в constexpr контекстах. На следующем заседании собираются принять в C++20.

Вдобавок нас попросили представить комитету два предложения, непосредственно над написанием которых мы не работали:

  • P0457R1 [11] — starts_with и ends_with для строк. Приняли в C++20. Шикарная штука!
  • P0458R0 [12] — функция contains(key) member для классов [unordered_]map/set/multimap/multiset. Отправили в LWG, на следующем заседании, возможно, примут в C++20.

Прочие новинки

  • range based for теперь может иметь следующий инициализатор:
    for (T thing = f(); auto& x : thing.items())
  • Отныне можно конструировать лямбды без состояния:
    using greater_t = decltype([](auto x, auto y) { return x > y; });
    std::map<std::string, int, greater_t> map;
    constexpr greater_t comparator{}; // OK
  • std::is_pod и std::is_pod_v помечены как deprecated.
  • Добавили новый type trait std::remove_cvref.
  • Атрибут [[nodiscard]] добавили к функциям async(), new, allocate(), empty() и launder().
  • std::memory_order* теперь доступны в виде scoped enum.
  • Добавили атомарные умные указатели:
    template <class T> struct atomic<shared_ptr<T>>;
    template <class T> struct atomic<weak_ptr<T>>;
  • Добавили поддержку чисел с плавающей точкой в std::atomic.
  • Множество мелких улучшений и багфиксов.

Параллельно кипела работа по подготовке к Modules TS и были добавлены множественные небольшие улучшения для Networking TS.

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

У вас есть идеи для C++20? Нашли проблемы в C++17, 14 или 11? Просто хотите подстегнуть разработку той или иной фичи C++? Заходите на сайт рабочей группы: stdcpp.ru [13]. Добро пожаловать!

Есть желание помочь с написанием предложений и внести своё имя в историю? Мы подготовили мини-инструкцию по написанию предложений [14].

27 ноября состоится встреча РГ21, где будет телемост с Гербом Саттером [15] и несколько выступлений. Приходите — вот ссылка на регистрацию [16]. Наконец, готовится встреча C++ User Group [17] в Нижнем Новгороде.


* Во всех этих случаях в стандарт приняли несколько обновлённые версии.

Автор: antoshkka

Источник [18]


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

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

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

[1] центральной части: https://habrahabr.ru/company/yandex/blog/336264/

[2] в этом документе: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0515r2.pdf

[3] здесь: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0768r0.pdf

[4] этой бумаге: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0053r6.pdf

[5] РГ21: https://habrahabr.ru/company/yandex/blog/301514/

[6] P0539R2: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0539r2.html

[7] P0415R0: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0415r0.html

[8] P0202R2: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0202r2.html

[9] P0275R2: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0275r2.html

[10] P0858R0: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0858r0.html

[11] P0457R1: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0457r1.html

[12] P0458R0: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0458r0.html

[13] stdcpp.ru: https://stdcpp.ru

[14] мини-инструкцию по написанию предложений: https://stdcpp.ru/podgotovka-predlozheniya-v-standart-c-instruktsiya

[15] Гербом Саттером: https://ru.wikipedia.org/wiki/%D0%A1%D0%B0%D1%82%D1%82%D0%B5%D1%80,_%D0%93%D0%B5%D1%80%D0%B1

[16] ссылка на регистрацию: https://events.yandex.ru/events/cpp-party/27-nov-2017/

[17] встреча C++ User Group: http://cpp-russia.ru/?p=1436

[18] Источник: https://habrahabr.ru/post/342354/