S>А зачем здесь еще и `operator==` как default? S>Вроде бы если мы декларируем `operator<=>` как default, то и операторы равенства/неравенства автоматически выводятся.
Да, действительно, спасибо. Выходит, это у меня в какой-то момент возникло недопонимание. Нужно будет ещё раз пройтись по этому вопросу.
Всему виной порочные подходы к изучению материала. Главные методы — попробовать на зуб и поколупать ногтем. Чтение мануала — только в самом крайнем случае
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Ну так вот именно. В т.ч. и сложить яблоки с апельсинами. Почему я и говорю, что не хотелось бы, чтоб это становилось обычным паттерном проектирования/кодирования. Когда подобные приведения размазаны толстым слоем по всему коду, не заметить бессмысленное действие — как два пальца об асфальт. Сам паттерн Strong Typedef обесценивается при этом.
В Go есть typedef в стиле Си. Называется он type alias:
type Oranges = int
Ввели его существенно позже и под предлогом, что в процессе рефакторинга большого проекта бывает так, что типы переезжают с места на место (из пакета в пакет), но не всегда получается всё порефакторить одним куском, и type alias позволяет временно одному пакету сослаться на (как бы затащить к себе) тип из другого пакета.
На практике, применяются type alias-ы довольно редко. В общем-то настолько редко, что мне пришлось в гугле синтаксис уточнить, чтобы не ошибиться
Здравствуйте, rg45, Вы писали:
R>Да, действительно, спасибо. Выходит, это у меня в какой-то момент возникло недопонимание. Нужно будет ещё раз пройтись по этому вопросу.
R>Всему виной порочные подходы к изучению материала. Главные методы — попробовать на зуб и поколупать ногтем. Чтение мануала — только в самом крайнем случае
Хорошие методы. Рабочие. Книжки, конечно, надо читать и теорию надо знать, но не попробовав на зуб, от теории немного толку.
Мне кажется, тут всему виной избыточная сложность изучаемого.
Ты вот производишь впечатление довольно толкового человека, а всё равно запутался. Невозможно постичь непостижимое
Здравствуйте, rg45, Вы писали:
S>>Вроде бы если мы декларируем `operator<=>` как default, то и операторы равенства/неравенства автоматически выводятся.
R>Да, действительно, спасибо. Выходит, это у меня в какой-то момент возникло недопонимание. Нужно будет ещё раз пройтись по этому вопросу.
Вроде бы определять свой `operator==` нужно только если мы сами делаем недефолтный `operator<=>`. Типа если у нас 5 полей, а в сравнении должно участвовать только 4, то вынуждены делать собственный `operator<=>`. Но т.к. это не дефолтная реализация, то к ней придется сделать и собственный `operator==`
Здравствуйте, so5team, Вы писали:
S>Вроде бы определять свой `operator==` нужно только если мы сами делаем недефолтный `operator<=>`. Типа если у нас 5 полей, а в сравнении должно участвовать только 4, то вынуждены делать собственный `operator<=>`. Но т.к. это не дефолтная реализация, то к ней придется сделать и собственный `operator==`
Мне сейчас уже сложно восстановить в памяти всю предысторию. Я помню только, что на самых начальных этапах моего знакомства с three-way comparison я столкнулся с тем, что без объявления operator == у меня не появилось ни ==, ни !=. Трудно сказать, почему так случилось — то ли какой-то особый случай, то ли баг msvc. Но я из того неудачного случая сделал ошибочное обобщение.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Marty, Вы писали:
M>Обнаружил, что таких операторов в плюсах нет
А ещё нет оператора =>
Я бы его добавил исключительно для перегрузки, без возможности применять со встроенными типами.
M>Интересно, а с чего?
Для меня выражения a &&= expr();
и a ||= expr();
несколько контринтуитивны, ведь вычисления expr() должны производиться не всегда, а только в случае если a == true для первого и a == false для второго, а это вроде как присваивания...
И вообще, код вида
result = result && fun0();
result = result && fun1();
result = result && fun2();
result = result || fun3();
result = result || fun4();
меня всегда напрягает при чтении, особенно если таких строчек с десяток. Видя такой код я каждый раз начинаю сомневаться в умственных способностях автора: то ли автор гениален и реально понимает, что делает этот код, то ли автор не учитывает всех последствий и просто "забил" на обработку ошибок.
И ещё, я знал авторов, которых нисколько не смущало отсутствие &&= в языке. Видел в коде вот такое:
bool bOk = true;
bOk &= fun1();
bOk &= fun2();
bOk &= fun3();
return bOk;
Короче, у меня есть большие сомнения оправданности такого рода подходов.
Здравствуйте, Pzz, Вы писали:
Pzz>Выглядит как-то несимметрично. И такое сравнение с тремя вариантами ответов — это одна ассемблерная команда для целочисленных типов (и еще одна-две, чтобы нормализовать результат). И такое сравнение очень часто встречается.
Pzz>Но заводить для него еще один мутный оператор...
Этот оператор непротиворечивым способом вводит все операторы сравнения.
Во-первых, без него тебе пришлось бы писать 6 штук. Выразив их через <, например.
Во-вторых, троичное сравнение экономнее — если сравнение является дорогой операцией (например, для строк)
if (a < b) { ... } // сравнили разelse if (b < a) { ... } // сравнили дваelse { ... }
// vsauto c = (a <=> b); // результат может быть разных типов - weak / partial / strong orderingif (c < 0) { ... }
else if (c > 0) { ... }
else if (c == 0) { ... }
else { ... } // несравнимые - например, если один из операндов - NaN
Pzz>А почему нет оператора, который возвращает за раз частное и остаток от деления? Тоже тот случай, когда результат даёт одна ассемблерная команда, а по-сишному надо писать две строки (которые развернутся в две одинаковые команды, если компилятор достаточно наивен).
Здравствуйте, so5team, Вы писали:
S>Вроде бы определять свой `operator==` нужно только если мы сами делаем недефолтный `operator<=>`. Типа если у нас 5 полей, а в сравнении должно участвовать только 4, то вынуждены делать собственный `operator<=>`. Но т.к. это не дефолтная реализация, то к ней придется сделать и собственный `operator==`
Скорее всего, это и был тот самый сценарий, который ввел меня в заблуждение.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, Marty, Вы писали:
M>>Кстати, а почему ты считаешь, что результат должен быть строго типа bool? Для || и && такого требования нет
R>Как это нет? И какой, по-твоему, тип результата, кроме bool, может быть, например, у выражения 42 && 43? int, что ли?
Это про встроенные в язык.
У пользовательских перегрузок может быть любой тип возврата.
struct A {
friend A operator&&(A const&, int a) {
return A();
}
};
int main() {
A a;
a = a && 5;
}
Основаная причина почему не перегружают, это потеря оптимизированного невычисления второй части выражения.
Более интересен вопрос, а что за случай такой, что нужно перегрузить &&, ||.
Здравствуйте, Кодт, Вы писали:
Pzz>>А почему нет оператора, который возвращает за раз частное и остаток от деления? Тоже тот случай, когда результат даёт одна ассемблерная команда, а по-сишному надо писать две строки (которые развернутся в две одинаковые команды, если компилятор достаточно наивен).
К>функция std::div https://en.cppreference.com/w/cpp/numeric/math/div К>которая может быть реализована на конкретной платформе через какой-нибудь интринсик.
С функцией, которав возвращает структуру, каждый может. Это было в Си, еще когда ANSI-стандарт был драфтом.
Тут надо бы какой-нибудь вырвиглазный новый синтаксис. Ну, например, x, y = a /% b;
И еще лет пять разгребать последствия. Например, можно ли результат такой операции использовать при вызове функции, и как сколько операндов он будет засчитан?
Здравствуйте, Pzz, Вы писали:
Pzz>>>А почему нет оператора, который возвращает за раз частное и остаток от деления? Тоже тот случай, когда результат даёт одна ассемблерная команда, а по-сишному надо писать две строки (которые развернутся в две одинаковые команды, если компилятор достаточно наивен).
К>>функция std::div https://en.cppreference.com/w/cpp/numeric/math/div К>>которая может быть реализована на конкретной платформе через какой-нибудь интринсик.
Pzz>С функцией, которав возвращает структуру, каждый может. Это было в Си, еще когда ANSI-стандарт был драфтом.
Pzz>Тут надо бы какой-нибудь вырвиглазный новый синтаксис. Ну, например, x, y = a /% b;
Продвинутый язык (а не убожества вроде Си и Go, говнокодить на которых вы привыкли) дает вам возможность сделать недостающее своими руками. Например, в самом примитивном виде:
#include <iostream>
#include <cstdlib>
namespace div_demo
{
struct div_result
{
int quot;
int rem;
};
struct div_operand
{
int what;
};
[[nodiscard]]
div_result
operator/(div_operand x, int y)
{
const auto r = std::div(x.what, y);
return { r.quot, r.rem };
}
} // namespace div_demoint main()
{
using namespace div_demo;
auto [q, r] = div_operand{5} / 2;
std::cout << q << ", " << r << std::endl;
}
Pzz>И еще лет пять разгребать последствия. Например, можно ли результат такой операции использовать при вызове функции, и как сколько операндов он будет засчитан?
"Боярам впредь говорить не по писанному, дабы глупость каждого видна была".
Здравствуйте, Pzz, Вы писали:
Pzz>Тут надо бы какой-нибудь вырвиглазный новый синтаксис. Ну, например, x, y = a /% b;
А чего тут вырвиглазного? Анпак структур почти везде вроде есть, вот и в плюсики завезли
Pzz>И еще лет пять разгребать последствия. Например, можно ли результат такой операции использовать при вызове функции, и как сколько операндов он будет засчитан?
Ну, если функция принимает такую структуру, то в чем проблема?
А если нет — то сохраняешь структуру в переменной, или делаешь анпак, и передаёшь по отдельности. В чем проблемы и что тут пять лет разгребать?
R>>Как это нет? И какой, по-твоему, тип результата, кроме bool, может быть, например, у выражения 42 && 43? int, что ли?
_NN>Это про встроенные в язык. _NN>У пользовательских перегрузок может быть любой тип возврата.
Я пользовательские перегрузки сразу исключил из рассмотрения, потому что перегрузку операторов && и || принято считать дурным тоном: https://it.wikireading.ru/27502 — и как раз по причине нарушения естественной семантики операторов, что важно в данном контексте.
Да и что-то мне подсказывает, что и сам Марти эту возможность не рассматривал. Пускай меня поправит, если я ошибаюсь.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, so5team, Вы писали:
Pzz>>Тут надо бы какой-нибудь вырвиглазный новый синтаксис. Ну, например, x, y = a /% b;
S>Продвинутый язык (а не убожества вроде Си и Go, говнокодить на которых вы привыкли) дает вам возможность сделать недостающее своими руками.
У вас совсем нет чувства юмора? Не очевидно разве, что выделенное — это ехидство?
Я знаю, что в C++ можно так написать.
S> auto [q, r] = div_operand{5} / 2;
Вы действительно считаете, что выделенное — это удачный синтаксис?
Как минимум, в нём больше букв, чем в прямом вызове функции. Сам по себе тип div_operand ни для чего больше не нужен, кроме как чтобы было к чему оператор / приделать. Ничего осмысленного со значениями этого типа сделать нельзя (а чтобы стало можно, к нему надо еще простыню текста приписать).
В чуть более сложном случае, чем мы обсуждаем, преобразование в div_operand вызывает вопросы при чтении кода, что это за нах и какой в этом смысл. И вынуждает разбираться с десятком строк определения этого чудесного нового типа, хотя при вызове функции хватило бы к ней комментария.
Здравствуйте, Pzz, Вы писали:
Pzz>Я знаю, что в C++ можно так написать.
Вы знаете, что в C++ можно написать так: x, y = a /% b;?
S>> auto [q, r] = div_operand{5} / 2;
Pzz>Вы действительно считаете, что выделенное — это удачный синтаксис?
Это штатный синтаксис C++. Такой же, как и вот в таком случае:
file{ path{"/etc"} / "ssh" / "ssh_config" };
Pzz>Как минимум, в нём больше букв, чем в прямом вызове функции. Сам по себе тип div_operand ни для чего больше не нужен, кроме как чтобы было к чему оператор / приделать. Ничего осмысленного со значениями этого типа сделать нельзя (а чтобы стало можно, к нему надо еще простыню текста приписать).
Еще раз повторю вопрос: позориться еще не надоело?
Здравствуйте, so5team, Вы писали:
Pzz>>Я знаю, что в C++ можно так написать.
S>Вы знаете, что в C++ можно написать так: x, y = a /% b;?
Я знаю, что можно написать, как в вашем примере.
Вам бы продавщицей на базаре работать. Ваша манера вести разговор, всё время передёргивая и пытаясь свести его к пустой эмоциональной перебранке как раз свойственна этой культуре.
S>>> auto [q, r] = div_operand{5} / 2;
Pzz>>Вы действительно считаете, что выделенное — это удачный синтаксис?
S>Это штатный синтаксис C++. Такой же, как и вот в таком случае:
Вы действительно считаете, что использование этого синтаксиса в данном месте — удачная идея с точки зрения выразительности кода?
Pzz>>Как минимум, в нём больше букв, чем в прямом вызове функции. Сам по себе тип div_operand ни для чего больше не нужен, кроме как чтобы было к чему оператор / приделать. Ничего осмысленного со значениями этого типа сделать нельзя (а чтобы стало можно, к нему надо еще простыню текста приписать).
S>Еще раз повторю вопрос: позориться еще не надоело?
Здравствуйте, Pzz, Вы писали:
Pzz>Вам бы продавщицей на базаре работать. Ваша манера вести разговор, всё время передёргивая и пытаясь свести его к пустой эмоциональной перебранке как раз свойственна этой культуре.
Некто Pzz чуть ранее:
У вас совсем нет чувства юмора? Не очевидно разве, что выделенное — это ехидство?
Pzz>Вы действительно считаете, что использование этого синтаксиса в данном месте — удачная идея с точки зрения выразительности кода?
Был приведен пример, демонстрирующий несостоятельность слов некого Pzz чуть ранее:
а по-сишному надо писать две строки (которые развернутся в две одинаковые команды, если компилятор достаточно наивен
...
С функцией, которав возвращает структуру, каждый может. Это было в Си, еще когда ANSI-стандарт был драфтом.
С++ позволяет выразить то, чего вам не хватало. В отличии от.
S>>Еще раз повторю вопрос: позориться еще не надоело?
Pzz>Не позорьтесь, если вам надоело.
Тут одного персонажа, задававшего тупые вопросы и приносившего мнение ChatGPT, гоняли ссаными тряпками чтобы не засирал профильный форум своей тупизной.
Когда вы начинаете отзываться о C++, не зная предмета разговора, вот в таком духе:
Ну, C++ вообще делали какие-то маньяки.
То вас тоже следует гонять этими же самыми тряпками.
Мне, например, не нравится ни Go, ни Java. Но я же не бегаю по RSDN-у и не доношу свое веское (нет) мнение об создателях этих языков.
А если вы считаете, что вам можно выплескивать здесь известную субстанцию, то значит можно вам же на фейс ее и намазывать не взирая на возраст.