Как пользоваться гетерогенным поиском в set/map/… просто и давно известно — передаешь std::less<> вторым/третьим шаблонным аргументом и все само заработает, это все кому было интересно с 2014-го уже узнали. А вот, про unordered контейнеры информация
1) свежая и поэтому пока малоизвестная,
2) более сложная — просто передать std::-что-нибудь не получится,
но, к сожалению, именно про это в статье ничего — ни примеров, ни теории, нет.
На ваш взгляд, каким должен быть совершенный цикл в 2020м году?
Примерно таким, как у вас в статье, только в C++20 (23) можно использовать стандартные функции вместо самописных. range -> iota (https://gcc.godbolt.org/z/d3bqYK). enumerate и zip должны появиться в C++23, так это выглядит в range-v3 (https://gcc.godbolt.org/z/9EfMj5):
На счет поддержки C++ не правда. Поддержка C++20 появляется в GCC не позже чем в Clang-е. И почему это libc++ — "наиболее полная реализация стандартной библиотеки C++", чем libstdc++ хуже (в libstdc++ к примеру уже есть Ranges)? Да, Richard Smith работает над Clang-ом, зато LWG chair Jonathan Wakely работает над GCC. В целом в комитете по стандартизации разработчики GCC и Clang-а представлены одинаково.
Ок, давайте поиграем в игру "в интернете кто-то не прав".
Во-первых, в C++ контекстных кейвордов, как в том анекдоте (Сначала было мало. Пришли мы с женойmodule c import, стало вдвое больше). В частности, requires не контекстный keyword в этом легко убедиться, проверив компилируемость int requires;https://gcc.godbolt.org/z/b39cvz:
int final; // OK
int override; // OK
int module; // OK
int import; // OK
int requires; // Fail
Если вы сделаете member-function корутиной вы тоже ожидаете, что поля класса скопируются в coroutine frame?
Дискуссия о том, чтобы как-то улучшить статус-кво, как я понимаю заглохла: https://github.com/GorNishanov/coroutines-ts/issues/32
Почему не захватить this в capture-list лямбды? Тогда весь код внутри вышел бы чуть проще. Но так получилось, что, видимо, лямбда-корутины в компиляторе пока поддерживаются не полностью, поэтому такой код работать не будет.
"Создание неявных виртуальных деструкторов для полиморфных типов"
Плохая идея сама по себе, даже если бы не требовала слома ABI.
"возвращаемый тип у push_back может быть изменен, если сломать текущий ABI"
Можно поменять и не ломая ABI, как это сделали в C++20 для std::list::remove.
"А вообще, действительно ли нам нужен и push_back, и emplace_back?"
Объединить их можно было бы, но тут надо опять говорить об API а не ABI.
Обычно у объекта переведенного в пустое-но-валидное состояние потом вызывается деструктор. То есть для оптимизации компилятору нужно догадаться, что сумма 2-х действий: "зачистка" объекта (как правило, случающаяся внутри move constructor или move assignment) + вызов деструктора у "зачищенного" объекта это noop. Чтобы догадаться нужно много и интенсивно инлайнить, на практике такое далоко не всегда происходит.
Нет, в гцц он сравнивает указатели на массивы, в clang он сравнивает сами массивы.
Это и получится, если при обходе подобъектов не разобрать случай массивов, там уж как if-ы сложатся, декэим до указателей или идем перебирать элементы.
Загружал бы два байта сразу одной командой и сравнивал бы два байта сразу одной командой.
Вы говорите про ассемблер, очевидно, что в C++17 это не выразимо для ровно той структуры, что вы написали. Eсли быстродействие сравнения этих структур важно, есть много способов, как это написать.
Очевидно что в gcc, что в clang-е кодогенератор для defaulted operator == просто рекурсивно обходит подобъекты, я бы тоже так сделал в первом приближении. При этом ни там ни там случай массовов пока не рассмотрели отдельно. Вы завели issue? Уверен их быстро исправят. Что касается вашего первого примера с char a, b; то как бы вы написали его руками эффективнее?
Спасибо за объяснение, кажется, что действительно во всех случаях компилятор может выполнить copy elision. Правда, остается проблема, что сейчас для каждого компилятора есть пример, когда он эту отпимизацию не выполняет. То есть в отличие от guaranteed RVO, который был просто стандартизацией существующей практики, уже реализованной во всех компиляторах, чтобы поддержать ваш proposal вендорам придется поработать.
Ваше предложение (P2025) кажется классным, но вы уверены в его реализуемости? Ведь это потребует некоторого control-flow анализа на фронтэнде, и, к примеру, gcc прямо сейчас с ним не справляется: gcc.godbolt.org/z/kMKQq5
Если вы знаете какие-то примеры ошибок вообще и с концептами в частности, сообщайте нам, пожалуйста, о них. Исправление красного кода для нас (ReSharper C++) приоритет номер один.
Как пользоваться гетерогенным поиском в
set/map/… просто и давно известно — передаешьstd::less<>вторым/третьим шаблонным аргументом и все само заработает, это все кому было интересно с 2014-го уже узнали. А вот, про unordered контейнеры информация1) свежая и поэтому пока малоизвестная,
2) более сложная — просто передать
std::-что-нибудь не получится,но, к сожалению, именно про это в статье ничего — ни примеров, ни теории, нет.
Вместо вложенных циклов можно (но не факт что нужно) использовать cartesian_product (https://gcc.godbolt.org/z/vaasqq):
На счет поддержки C++ не правда. Поддержка C++20 появляется в GCC не позже чем в Clang-е. И почему это libc++ — "наиболее полная реализация стандартной библиотеки C++", чем libstdc++ хуже (в libstdc++ к примеру уже есть Ranges)? Да, Richard Smith работает над Clang-ом, зато LWG chair Jonathan Wakely работает над GCC. В целом в комитете по стандартизации разработчики GCC и Clang-а представлены одинаково.
Ок, давайте поиграем в игру "в интернете кто-то не прав".
Во-первых, в C++ контекстных кейвордов, как в том анекдоте (Сначала было мало. Пришли
мы с женойmodulecimport, стало вдвое больше). В частности,requiresне контекстный keyword в этом легко убедиться, проверив компилируемостьint requires;https://gcc.godbolt.org/z/b39cvz:Во-вторых, requires-expression может использоваться где угодно, к примеру (https://gcc.godbolt.org/z/zHRSg5)
Возможно, вас смутило, то что это пока не работает в MSVC, но они об этом честно предупреждали, анонсируя свою поддержку концептов.
Конечно, работает.
Это не правда,
requiresне контекстный, и использовать requires-expression не обязательно внутри шаблонов.И как это связано с coroutine frame?
Если вы сделаете member-function корутиной вы тоже ожидаете, что поля класса скопируются в coroutine frame?
Дискуссия о том, чтобы как-то улучшить статус-кво, как я понимаю заглохла: https://github.com/GorNishanov/coroutines-ts/issues/32
Это типичная ошибка работы с корутинами: https://quuxplusone.github.io/blog/2019/07/10/ways-to-get-dangling-references-with-coroutines/#exciting-new-way-to-dangle-a-reference и нет, это не недоделка в компиляторе.
Добавлю к списку:
Плохая идея сама по себе, даже если бы не требовала слома ABI.
Можно поменять и не ломая ABI, как это сделали в C++20 для
std::list::remove.Объединить их можно было бы, но тут надо опять говорить об API а не ABI.
Разве понятие "implicitly creating objects" вошло в C++20? p0593 ведь отложили до C++23.
Обычно у объекта переведенного в пустое-но-валидное состояние потом вызывается деструктор. То есть для оптимизации компилятору нужно догадаться, что сумма 2-х действий: "зачистка" объекта (как правило, случающаяся внутри move constructor или move assignment) + вызов деструктора у "зачищенного" объекта это noop. Чтобы догадаться нужно много и интенсивно инлайнить, на практике такое далоко не всегда происходит.
Это и получится, если при обходе подобъектов не разобрать случай массивов, там уж как if-ы сложатся, декэим до указателей или идем перебирать элементы.
Вы говорите про ассемблер, очевидно, что в C++17 это не выразимо для ровно той структуры, что вы написали. Eсли быстродействие сравнения этих структур важно, есть много способов, как это написать.
Что же до примера с полем
char a[32];замените тип наarray<char, 32>и будет то что вы хотите: https://godbolt.org/z/x9KebqОчевидно что в gcc, что в clang-е кодогенератор для defaulted operator == просто рекурсивно обходит подобъекты, я бы тоже так сделал в первом приближении. При этом ни там ни там случай массовов пока не рассмотрели отдельно. Вы завели issue? Уверен их быстро исправят. Что касается вашего первого примера с char a, b; то как бы вы написали его руками эффективнее?
https://youtrack.jetbrains.com/issue/RSCPP-24125 (пункт 1.3)
Спасибо за объяснение, кажется, что действительно во всех случаях компилятор может выполнить copy elision. Правда, остается проблема, что сейчас для каждого компилятора есть пример, когда он эту отпимизацию не выполняет. То есть в отличие от guaranteed RVO, который был просто стандартизацией существующей практики, уже реализованной во всех компиляторах, чтобы поддержать ваш proposal вендорам придется поработать.
Это не такой уж простой анализ. Я же правильно понимаю, что в этом (https://gcc.godbolt.org/z/fKFT6d) случае
copy elision тоже гарантируется? А как насчет goto? (https://gcc.godbolt.org/z/HB09nk).