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

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

542xct8oihlwbtiirqmdyel5zpg.png

На встрече международного комитета по стандартизации 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  // 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);
    }
};


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

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

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


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

osyncstream


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

#include 
#include 
#include 

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 
#include 
#include 

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();
}


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

Заслуги РГ21


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

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


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

  • P0457R1 — starts_with и ends_with для строк. Приняли в C++20. Шикарная штука!
  • P0458R0 — функция 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 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  struct atomic>;
    template  struct atomic>;
  • Добавили поддержку чисел с плавающей точкой в std: atomic.
  • Множество мелких улучшений и багфиксов.


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

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


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

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

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

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

© Habrahabr.ru