Здравствуйте, 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>Здравствуйте, Marty, Вы писали:
M>>Обнаружил, что таких операторов в плюсах нет
M>>Интересно, а с чего?
Pzz>Сколько ты перед тем написал плюсового кода, не зная, что таких операторов в плюсах нет? Наверное, их нет потому, что они не слишком нужны.
Здравствуйте, rg45, Вы писали:
R>Ну, наверное потому, что у всех булевских операторов типы операндов могут быть очень многообразны, а тип результата всегда строго bool. Ну, например, каким должен быть результат оператора &&= для двух операндов типа int? Вот чтобы избежать всяких подобных вопросов, эти операторы и не стали вводить.
Таким же, как a = a && b; Со всем связанным с этим комплексом неудобных вопросов.
Но судя по тому, что Марти обнаружил отсутствие операторов &&= и ||= где-то, насколько я понимаю, примерно на сороковом году жизни, наверное они и вправду бывают нечасто нужны.
Здравствуйте, rg45, Вы писали:
S>>Вроде бы если мы декларируем `operator<=>` как default, то и операторы равенства/неравенства автоматически выводятся.
R>Да, действительно, спасибо. Выходит, это у меня в какой-то момент возникло недопонимание. Нужно будет ещё раз пройтись по этому вопросу.
Вроде бы определять свой `operator==` нужно только если мы сами делаем недефолтный `operator<=>`. Типа если у нас 5 полей, а в сравнении должно участвовать только 4, то вынуждены делать собственный `operator<=>`. Но т.к. это не дефолтная реализация, то к ней придется сделать и собственный `operator==`
А зачем здесь еще и `operator==` как default?
Вроде бы если мы декларируем `operator<=>` как default, то и операторы равенства/неравенства автоматически выводятся.
1 The && operator groups left-to-right. The operands are both contextually converted to bool ([conv]). The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
2 The result is a bool. If the second expression is evaluated, the first expression is sequenced before the second expression ([intro.execution]).
1 The || operator groups left-to-right. The operands are both contextually converted to bool ([conv]). The result is true if either of its operands is true, and false otherwise. Unlike |, || guarantees left-to-right evaluation; moreover, the second operand is not evaluated if the first operand evaluates to true.
2 The result is a bool. If the second expression is evaluated, the first expression is sequenced before the second expression ([intro.execution]).
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, Нomunculus, Вы писали:
Pzz>>Сколько ты перед тем написал плюсового кода, не зная, что таких операторов в плюсах нет? Наверное, их нет потому, что они не слишком нужны.
Н>Зато есть офигеть какой нужный spaceship — <=>
Пипец какой. Я не знал.
В принципе, идею понять можно.
if (a < b)
return -1;
if (a > b)
return 1;
returm 0;
Выглядит как-то несимметрично. И такое сравнение с тремя вариантами ответов — это одна ассемблерная команда для целочисленных типов (и еще одна-две, чтобы нормализовать результат). И такое сравнение очень часто встречается.
Но заводить для него еще один мутный оператор...
А почему нет оператора, который возвращает за раз частное и остаток от деления? Тоже тот случай, когда результат даёт одна ассемблерная команда, а по-сишному надо писать две строки (которые развернутся в две одинаковые команды, если компилятор достаточно наивен).
Здравствуйте, Pzz, Вы писали:
Pzz>Альфа бы, конечно, сказал, что он умный и никогда не будет складывать яблоки с апельсинами, и ему лишний контроль не нужен.
Альфа бы сказал, что сложение и вычитание требует одинаковости типов, а умножение и деление — нет.
Но эта мысль слишком сложная и для современных компьютеров и для современных программистов.
Кроме того нужно как-то описывать что получается при умножении и при делении.
Когда умножаешь метры на метры, то получаются не метры а квадратные метры.
Вот и попробуй всё это описать.
Поэтому да — или вы обеспечиваете нормальный контроль, или ну его на фиг.
Здравствуйте, so5team, Вы писали:
A>>Кроме того нужно как-то описывать что получается при умножении и при делении. A>>Когда умножаешь метры на метры, то получаются не метры а квадратные метры. A>>Вот и попробуй всё это описать.
S>Ну как-то же пробуют: https://github.com/mpusz/mp-units
И как успехи? Породили ещё один монстрообразный и ненужный проект?
Ты-ж понимаешь, что метры — это только для примера.
Мне в моей программе понадобятся свои типы и свои величины.
И какого размера монстрика я должен для этого породить?
Здравствуйте, B0FEE664, Вы писали:
BFE>ИИ меня упорно убеждает, что запись вида a && (a = expr()); — это неопределённое поведение. Раз выражении одно, то плевать на определённость порядка...
Здравствуйте, Marty, Вы писали:
M>Здравствуйте! M>Обнаружил, что таких операторов в плюсах нет M>Интересно, а с чего?
Ну, наверное потому, что у всех булевских операторов типы операндов могут быть очень многообразны, а тип результата всегда строго bool. Ну, например, каким должен быть результат оператора &&= для двух операндов типа int? Вот чтобы избежать всяких подобных вопросов, эти операторы и не стали вводить.
А ещё нет булевского XOR. Наверное потому, что для операндов булевского типа его результат всегда совпадает с результатом оператора !=, а для операндов других типов опять возникают всякие неудобные вопросики.
--
Справедливость выше закона. А человечность выше справедливости.
R>А ещё нет булевского XOR. Наверное потому, что для операндов булевского типа его результат всегда совпадает с результатом оператора !=, а для операндов других типов опять возникают всякие неудобные вопросики.
Да, тут у меня тоже возник вопрос — битовый XOR по приоритету между OR и AND, а логический XOR, который не равно, имеет приоритет выше AND
Здравствуйте, rg45, Вы писали:
R>Ну, наверное потому, что у всех булевских операторов типы операндов могут быть очень многообразны, а тип результата всегда строго bool. Ну, например, каким должен быть результат оператора &&= для двух операндов типа int? Вот чтобы избежать всяких подобных вопросов, эти операторы и не стали вводить.
Кстати, а почему ты считаешь, что результат должен быть строго типа bool? Для || и && такого требования нет
Здравствуйте, Marty, Вы писали:
M>Да, тут у меня тоже возник вопрос — битовый XOR по приоритету между OR и AND, а логический XOR, который не равно, имеет приоритет выше AND
Более смешно то, что в разных языках, произошедших от Си, по-разному расставлены приоритеты похожих операций.
Здравствуйте, Pzz, Вы писали:
Pzz>Таким же, как a = a && b; Со всем связанным с этим комплексом неудобных вопросов.
Pzz>Но судя по тому, что Марти обнаружил отсутствие операторов &&= и ||= где-то, насколько я понимаю, примерно на сороковом году жизни, наверное они и вправду бывают нечасто нужны.
Ну да, непротиворечивые правила можно было бы придумать. Тем не менее, всё равно существовала бы другая чаша весов, на которой находился бы принцип наименьшего удивления. И эта другая чаша оказывается несколько тяжелее, чем в случае других операторов.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
Pzz>>Но судя по тому, что Марти обнаружил отсутствие операторов &&= и ||= где-то, насколько я понимаю, примерно на сороковом году жизни, наверное они и вправду бывают нечасто нужны.
R>Ну да, непротиворечивые правила можно было бы придумать. Тем не менее, всё равно существовала бы другая чаша весов, на которой находился бы принцип наименьшего удивления.
Мне нравится подход Go. Там нет автоматического приведения целочисленных типов.
Даже вот такая конструкция:
type int Oranges
type int Apples
type int Fruits
var o Oranges
var a Apples
var f Ftuits
f = o + a
Вызовет ошибку времени компиляции при попытке сложить яблоки с апельсинами без явного приведения типов.
Хотя все три типа определены через int, это три разных типа (но приводимых друг к другу).
Pzz>type int Oranges
Pzz>type int Apples
Pzz>type int Fruits
Pzz>var o Oranges
Pzz>var a Apples
Pzz>var f Ftuits
Pzz>f = o + a
Pzz>
Pzz>Вызовет ошибку времени компиляции при попытке сложить яблоки с апельсинами без явного приведения типов.
Ну тут палка о двух концах. Ровно с тем же успехом она не позволит выполнить и вполне осмысленное действие, например, разделить километры на часы. В С++, конечно, приходится делать больше телодвижений, но полнота контроля получается больше. А тут получается по принципу: "делай, что тебе говорят и будь счастлив".
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
Pzz>>Вызовет ошибку времени компиляции при попытке сложить яблоки с апельсинами без явного приведения типов.
R>Ну тут палка о двух концах. Ровно с тем же успехом она не позволит выполнить и вполне осмысленное действие, например, разделить километры на часы. В С++, конечно, приходится делать больше телодвижений, но полнота контроля получается больше. А тут получается по принципу: "делай, что тебе говорят и будь счастлив".
Можно явно привести.
Альфа бы, конечно, сказал, что он умный и никогда не будет складывать яблоки с апельсинами, и ему лишний контроль не нужен.
Но бывает так, что работаешь, например, со сложной иерархией структур, и в них есть битовые поля, и в разных структурах они разные (с разным назначением битов). Ну, к примеру, иерархия дескрипторов USB. В Configuration Descriptor у поля bMAttributes свои биты, в Endpoint Descriptor — свои, а поля одинаково называются. Немудрено и напутать.
А если обозвать их разными типами, то (1) не перепутаешь (2) не надо даже как-то в комментариях особо выделять, какие биты к чему относятся, это выражено в самом коде.
Но так да. Если делишь километры на часы, придется сказать компилятору, что ты понимаешь, что делаешь.
Здравствуйте, Pzz, Вы писали:
Pzz>Можно явно привести.
Ну вот этого как раз и не хотелось бы. Это примерно то же самое, как при работе с типизированными указателями на каждый чих приходилось бы приводить их к void*.
Pzz>Альфа бы, конечно, сказал, что он умный и никогда не будет складывать яблоки с апельсинами, и ему лишний контроль не нужен.
Pzz>Но бывает так, что работаешь, например, со сложной иерархией структур, и в них есть битовые поля, и в разных структурах они разные (с разным назначением битов). Ну, к примеру, иерархия дескрипторов USB. В Configuration Descriptor у поля bMAttributes свои биты, в Endpoint Descriptor — свои, а поля одинаково называются. Немудрено и напутать.
Pzz>А если обозвать их разными типами, то (1) не перепутаешь (2) не надо даже как-то в комментариях особо выделять, какие биты к чему относятся, это выражено в самом коде.
Ну это понятно. Это старый добрый паттерн Strong Typedef, полезность которого не вызывает вопросов. Некоторый дискомфорт всё же возникает по поводу того, что этот паттерн гвоздями прибит к языку. Возможно, это просто с непривычки.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
Pzz>>Можно явно привести.
R>Ну вот этого как раз и не хотелось бы. Это примерно то же самое, как при работе с типизированными указателями на каждый чих приходилось бы приводить их к void*.
Ну, через void* можно что угодно к чему угодно привести, без какого-либо контроля.
В данном случае компилятор всё же не даст сделать какую-то полную дичь. Например, сравнить число со строкой.
R>Ну это понятно. Это старый добрый паттерн Strong Typedef, полезность которого не вызывает вопросов. Некоторый дискомфорт всё же возникает по поводу того, что этот паттерн гвоздями прибит к языку. Возможно, это просто с непривычки.
Не раздражает. В рееальном коде редко встречается.
Здравствуйте, Pzz, Вы писали:
R>>Ну вот этого как раз и не хотелось бы. Это примерно то же самое, как при работе с типизированными указателями на каждый чих приходилось бы приводить их к void*.
Pzz>Ну, через void* можно что угодно к чему угодно привести, без какого-либо контроля.
Ну так вот именно. В т.ч. и сложить яблоки с апельсинами. Почему я и говорю, что не хотелось бы, чтоб это становилось обычным паттерном проектирования/кодирования. Когда подобные приведения размазаны толстым слоем по всему коду, не заметить бессмысленное действие — как два пальца об асфальт. Сам паттерн Strong Typedef обесценивается при этом.
--
Справедливость выше закона. А человечность выше справедливости.
S>А зачем здесь еще и `operator==` как default? S>Вроде бы если мы декларируем `operator<=>` как default, то и операторы равенства/неравенства автоматически выводятся.
Да, действительно, спасибо. Выходит, это у меня в какой-то момент возникло недопонимание. Нужно будет ещё раз пройтись по этому вопросу.
Всему виной порочные подходы к изучению материала. Главные методы — попробовать на зуб и поколупать ногтем. Чтение мануала — только в самом крайнем случае
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Ну так вот именно. В т.ч. и сложить яблоки с апельсинами. Почему я и говорю, что не хотелось бы, чтоб это становилось обычным паттерном проектирования/кодирования. Когда подобные приведения размазаны толстым слоем по всему коду, не заметить бессмысленное действие — как два пальца об асфальт. Сам паттерн Strong Typedef обесценивается при этом.
В Go есть typedef в стиле Си. Называется он type alias:
type Oranges = int
Ввели его существенно позже и под предлогом, что в процессе рефакторинга большого проекта бывает так, что типы переезжают с места на место (из пакета в пакет), но не всегда получается всё порефакторить одним куском, и type alias позволяет временно одному пакету сослаться на (как бы затащить к себе) тип из другого пакета.
На практике, применяются type alias-ы довольно редко. В общем-то настолько редко, что мне пришлось в гугле синтаксис уточнить, чтобы не ошибиться
Здравствуйте, rg45, Вы писали:
R>Да, действительно, спасибо. Выходит, это у меня в какой-то момент возникло недопонимание. Нужно будет ещё раз пройтись по этому вопросу.
R>Всему виной порочные подходы к изучению материала. Главные методы — попробовать на зуб и поколупать ногтем. Чтение мануала — только в самом крайнем случае
Хорошие методы. Рабочие. Книжки, конечно, надо читать и теорию надо знать, но не попробовав на зуб, от теории немного толку.
Мне кажется, тут всему виной избыточная сложность изучаемого.
Ты вот производишь впечатление довольно толкового человека, а всё равно запутался. Невозможно постичь непостижимое
Здравствуйте, so5team, Вы писали:
S>Вроде бы определять свой `operator==` нужно только если мы сами делаем недефолтный `operator<=>`. Типа если у нас 5 полей, а в сравнении должно участвовать только 4, то вынуждены делать собственный `operator<=>`. Но т.к. это не дефолтная реализация, то к ней придется сделать и собственный `operator==`
Мне сейчас уже сложно восстановить в памяти всю предысторию. Я помню только, что на самых начальных этапах моего знакомства с three-way comparison я столкнулся с тем, что без объявления operator == у меня не появилось ни ==, ни !=. Трудно сказать, почему так случилось — то ли какой-то особый случай, то ли баг msvc. Но я из того неудачного случая сделал ошибочное обобщение.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, 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-у и не доношу свое веское (нет) мнение об создателях этих языков.
А если вы считаете, что вам можно выплескивать здесь известную субстанцию, то значит можно вам же на фейс ее и намазывать не взирая на возраст.
Здравствуйте, Pzz, Вы писали:
Pzz>Вы меня преследуете что ли? Ну-ну.
Байку вспомнил. Один мужик поздней ночью пробирался домой тёмными дворами. Какой-то неожиданный звук испугал его. Мужик резко дёрнулся и в этот эе момент получил удар по голове, от которого упал и потерял сознание. Придя в себя, он быстро вскочил на ноги, но тут же опять получил удар по голове и опять упал. Так он вскакивал, получал удары и снова падал всю ночь. Наконец, рассвело. И мужик, открыв глаза, увидел над своей головой детский турник...
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, alpha21264, Вы писали:
A>Кроме того нужно как-то описывать что получается при умножении и при делении. A>Когда умножаешь метры на метры, то получаются не метры а квадратные метры. A>Вот и попробуй всё это описать.
Здравствуйте, rg45, Вы писали:
R>А ещё нет булевского XOR. Наверное потому, что для операндов булевского типа его результат всегда совпадает с результатом оператора !=, а для операндов других типов опять возникают всякие неудобные вопросики.
А ещё в Бейсике есть эквиваленция EQV и импликация IMP, в сях нет, но, возможно, и не нужно.
Здравствуйте, alpha21264, Вы писали:
Pzz>>Альфа бы, конечно, сказал, что он умный и никогда не будет складывать яблоки с апельсинами, и ему лишний контроль не нужен.
A>Альфа бы сказал, что сложение и вычитание требует одинаковости типов, а умножение и деление — нет.
Согласен.
A>Когда умножаешь метры на метры, то получаются не метры а квадратные метры. A>Вот и попробуй всё это описать.
Вот я думаю да. Не "слишком сложная мысль", а поди попробуй всё это описать.
A>Поэтому да — или вы обеспечиваете нормальный контроль, или ну его на фиг.
А вот тут не согласен. То, что уже сейчас есть, определённо лучше, чем ничего.
Заметим, кстати, что умножение и деление встречается в программах порядка на два, наверное, реже, чем сложение и вычитание. В частности поэтому для процессора без встроенных команд умножения и деления было вполне сносно программировать.
Здравствуйте, Maniacal, Вы писали:
M>А ещё в Бейсике есть эквиваленция EQV и импликация IMP, в сях нет, но, возможно, и не нужно.
Ну да, в сях в дополнение к логическим операциям есть битовые операции и операции с адресами. На этой базе программист может построить всё, что душе угодно.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, alpha21264, Вы писали:
S>>Ну как-то же пробуют: https://github.com/mpusz/mp-units
A>И как успехи? Породили ещё один монстрообразный и ненужный проект? A>Ты-ж понимаешь, что метры — это только для примера. A>Мне в моей программе понадобятся свои типы и свои величины. A>И какого размера монстрика я должен для этого породить?
Вроде бы планируют добавить эти наработки в С++29.
A>Породили ещё один монстрообразный и ненужный проект?
Если судить по количеству звезд на GitHub-е, далеко не "ненужный".
A>Ты-ж понимаешь, что метры — это только для примера.
Нет, не понимаю. Предпочитаю говорить предметно. В указанной mp-units поддержали большое количество существующих единиц измерения.
A>Мне в моей программе понадобятся свои типы и свои величины. A>И какого размера монстрика я должен для этого породить?
ХЗ, тут бы сперва узнать, а умеете ли вы программировать вообще. Вашего кода я не видел.
Здравствуйте, rg45, Вы писали:
A>>И как успехи? Породили ещё один монстрообразный и ненужный проект? A>>Ты-ж понимаешь, что метры — это только для примера. A>>Мне в моей программе понадобятся свои типы и свои величины. A>>И какого размера монстрика я должен для этого породить?
R>Ну вот ещё пример: Шаблончик для размерных величин
.
R>Обрати внимание на простоту и год — 2009-й. Тогда это поместилось на пол экрана, а в наше время хватило бы и четверти.
Ну, это несколько не то. Тут у тебя одна и та же величина, просто в разный единицах.
В прошлом веке для этого просто венгерская нотация использовалась.
То есть, задача "не перепутать единицы" была решена вообще без кода.
Да, компилятор ошибки не генерировал. Просто было видно какая переменная в каких единицах.
Здравствуйте, alpha21264, Вы писали:
A>Ну, это несколько не то. Тут у тебя одна и та же величина, просто в разный единицах. A>В прошлом веке для этого просто венгерская нотация использовалась. A>То есть, задача "не перепутать единицы" была решена вообще без кода. A>Да, компилятор ошибки не генерировал. Просто было видно какая переменная в каких единицах.
Ну да, есть такое дело. Но можно допилить, чтоб можно было определять и производные единицы измерения. При современных средствах языка можно добиться того, что эти объявления будут выглядеть декларативно и компактно.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, sergii.p, Вы писали:
SP>в javascript тоже так подумали, но так как там всё контринтуитивно, решили в язык добавить SP>https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND_assignment
Интересно. Интересно ещё, что
ИИ меня упорно убеждает, что запись вида a && (a = expr()); — это неопределённое поведение. Раз выражении одно, то плевать на определённость порядка...
Я в раздумьях...
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, vdimas, Вы писали: V>>Порядок вычисления аргументов && не определён. TB>
TB>if (p && p->x == 5) ...
TB>
Здесь явная точка последовательности — дважды читается одна и так же переменная p, т.е. с т.з. правого операнда все побочные эффекты вычисления левого операнда уже завершены.
В исходном примере, если компилятор в процессе оптимизации предположит, что "a" равно true, то начнёт писать в это "a" во втором выражении и результат может быть неопределённый из-за OoO.
Здравствуйте, vdimas, Вы писали:
BFE>>ИИ меня упорно убеждает, что запись вида a && (a = expr()); — это неопределённое поведение. Раз выражении одно, то плевать на определённость порядка... V>Порядок вычисления аргументов && не определён.
ЕМНИП порядок вычисления аргументов && не определён, только для пользовательской перегрузки.
Здравствуйте, vdimas, Вы писали:
V>Здесь явная точка последовательности — дважды читается одна и так же переменная p, т.е. с т.з. правого операнда все побочные эффекты вычисления левого операнда уже завершены.
Точки последовательности давно выкинули из стандарта .
V>В исходном примере, если компилятор в процессе оптимизации предположит, что "a" равно true, то начнёт писать в это "a" во втором выражении и результат может быть неопределённый из-за OoO.