Open apolukhin opened 3 years ago
yndx-antoshkka, 19 сентября 2018, 12:37 Идея супер! Предлагаю написать через operator<=> чтобы уменьшить количество перегрузок (+ надо заменить decay_t на remove_cv_ref_t)
Andrey Davydov, 19 сентября 2018, 14:03
А как насчет ослабить условие (... || std::is_same_v<Ts, T>)
? Хочется чтобы такой код тоже работал:
struct B {};
struct D : B {};
void test(D * d) {
std::variant<B*> v(d);
v == d;
}
Олег Фатхиев, 19 сентября 2018, 14:58 Andrey Davydov, не совсем понятно, как быть в таком случае.
А если у нас такой variant:
std::variant<int, char> v{ (char)5 };
v == (int)5;
Если ослабить проверку, то мы будем получать тут true, что, скорее всего, не является ожидаемым поведением, так как https://en.cppreference.com/w/cpp/utility/variant/operator_cmp делает даже более строгую проверку.
Andrey Davydov, 19 сентября 2018, 16:55 Олег Фатхиев, можно сделать так, что если Ts содержит T, то дополнительно проверять, что активный вариант типа T, иначе сравнивать даже разных типов. Все равно останется неитуитивное поведение в таком коде:
variant<string_view, bool> v("aba");
v == "aba"sv;
но тут уже ничего не поделаешь.
yndx-antoshkka, 24 сентября 2018, 16:24 Пока что, во избежание проблем, договорились делать так:
делать через operator<=>
разрешать (через enable_if подобные конструкции) эти операторы ТОЛЬКО если 1 альтернатива из variant сравнима с не-variant параметром
в случае если variant содержит valueless_by_exception() или не ту альтернативу, с которой хотим сравниться, то делать поведение аналогичное существующим операторам сравнения двух вариантов
yndx-antoshkka, 25 сентября 2018, 12:31 Черновик предложения: https://apolukhin.github.io/papers/variant_spaceship.html
Andrey Davydov, 25 сентября 2018, 13:07 yndx-antoshkka, кажется что смешение сравнения индексов и сравнения значений приводит к математически абсурдным результатам:
struct A {
bool operator == (A) const { return true; }
} a;
variant<A, int> x(a);
variant<int, A> y(a);
assert(x == a);
assert(y == a);
assert(x < 0);
assert(y > 0);
Andrey Davydov, 25 сентября 2018, 13:22 Если Вы и Олег согласны, что это проблема, то по предлагаю чинить ее понижением категории до std::partial_ordering (если у T она сильнее) и в случае
(v.index() <=> i) != 0
возвращать partial_ordering::unordered.
yndx-antoshkka, 25 сентября 2018, 14:15 Andrey Davydov, тогда не получится использовать variant с гетерогенными контейнерами.
Andrey Davydov, 25 сентября 2018, 14:39
yndx-antoshkka, Вы имеете в виду ordered контейнеры с гетерогенным lookup'ом (less
yndx-antoshkka, 25 сентября 2018, 15:48 Andrey Davydov, такое поведение точно будет не переносимым и взрывающим людям мозг. Нужно смириться с тем, что variant<A, int> и variant<int, A> это разные типы, и операторы сравнения с int у них ведут себя по разному.
А вот идея с функцией, сортирующей шаблоны - это мысль интересная, но для отдельного предложения.
Andrey Davydov, 25 сентября 2018, 16:26 yndx-antoshkka,
такое поведение точно будет не переносимым и взрывающим людям мозг
Я не очень хорошо понимаю значение "непереносимым" в данном контексте. Оно будет implementation defined, но поставленную задачу -- гетерогенный lookup в ordered контейнере variant'ов оно решает. Ведь есть же уже прецендент std::type_index, да его сравнение implementation-defined, зато std::set
Нужно смириться с тем, что variant<A, int> и variant<int, A> это разные типы
Это только если мы не верим в транзитивность, в моем примере (x == a) и (y == a), так что не такие уж они и разные. А если добавить
template<typename V1, typename V2>
requires(TemplateArgsAreEqualByModuloOfPermutation<V1, V2>)
std::[strong|weak]_equality operator <=> (V1 const &, V2 const &);
что лично мне кажется, куда более естественным, чем ordering вводимый предлагаемым способом, "смириться" точно не получится.
Andrey Davydov, 2 октября 2018, 6:58 yndx-antoshkka, в черновике (Motivation) есть опечатки в комментарии -- "grater" -> "greater" и, возможно, не хватает "?" в конце первой строки.
yndx-antoshkka, 2 октября 2018, 19:30 Andrey Davydov, спасибо, подправил (ещё не выложил обновлённую версию)
Комитет несколько пугает перегрузка операторов отличных от ==
. Нужно поработать над мотивацией, возможно оставить только операторы сравнения на равенство.
Перенос предложения: голоса +9, -0 Автор идеи: Олег Фатхиев
Предлагаю добавить следующие операторы: