Есть какое-нибудь логическое объяснение, почему в С++ отсутствуют операторы:
&&=
||=
логическое XOR (^^ или что-то подобное)
Как-то несимметрично получается...
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>А для чего, если не секрет, они Вам нужны? С примерами пожалуйста.
Странный вопрос. Каждый бинарный оператор имеет соответствующий оператор с присваиванием. Исключение составляет лишь логические операторы || и &&.
Логическое XOR — это, по-моему, вообще очевидно.
Пример:
Здравствуйте, Lorenzo_LAMAS, Вы писали:
S>>Вы, батенька, логические операторы с побитовыми не путайте, для разных целей всё-таки.
L_L>Так он не путает. Ему хочется &&= для переменных типа bool.
Совершенно верно. И совершенно непонятно, почему для логических операторов нет сдвоенных с присваиванием.
Я жуе не говорю про логический xor.
Конечно, можно сделать
inline bool Xor(bool x1,bool x2)
{
return (x1&&(!x2))||(x2&&(!x1))
}
Но, согласитель, некрасиво. И вряд ли эффективно.
Здравствуйте, sercher, Вы писали:
S>А чем это не устраивает:
S>[ccode] S>int result = false; S>result &= First(); S>result |= Second(); S>result &= Third();
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>Здравствуйте, sercher, Вы писали:
S>>А чем это не устраивает:
S>>[ccode] S>>int result = false; S>>result &= First(); S>>result |= Second(); S>>result &= Third();
ЕК>Не надо путать битовые операции и логические.
ЕК>2 & 4 == false (0) ЕК>2 && 4 == true
ЕК>Это разные операции.
Как мне кажется, эта проблема надумана. В каждом языке (и не только) происходят эволюционнные процессы, и уж за три десятка лет существования С/С++ такое предложение возникало неоднократно.
Но скорее всего оно не находило поддержки по простой причине: люди (т.е. программисты) не склоны производить ВЫЧИСЛЕНИЯ с булевскими типами (ну какой прок скажем от операции bool + bool или bool — bool, что будет в результате?). Данный тип служит только для индикации того, что какое-то утверждение истинно или ложно и не более того. ("Я так думаю" (с) Мимино)
S>Как мне кажется, эта проблема надумана. В каждом языке (и не только) происходят эволюционнные процессы, и уж за три десятка лет существования С/С++ такое предложение возникало неоднократно. S>Но скорее всего оно не находило поддержки по простой причине: люди (т.е. программисты) не склоны производить ВЫЧИСЛЕНИЯ с булевскими типами (ну какой прок скажем от операции bool + bool или bool — bool, что будет в результате?). Данный тип служит только для индикации того, что какое-то утверждение истинно или ложно и не более того. ("Я так думаю" (с) Мимино)
конечно, bool+bool смысла не имеет. А вот bool && bool ещё как имеет.
Дело в том, что из С унаследована роль int как bool. Это приводит к некоторой путанице.
Это — не расширение С++. Вообще, когда я столкнулся с отсутствием этих операторов, я был удивлён.
А что касается "можно обойтись без этого" — понятное дело. Можно обойтись машиной Тьюринга.
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>Я жуе не говорю про логический xor. ЕК>Конечно, можно сделать ЕК>inline bool Xor(bool x1,bool x2) ЕК>{ ЕК> return (x1&&(!x2))||(x2&&(!x1)) ЕК>} ЕК>Но, согласитель, некрасиво. И вряд ли эффективно.
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>Есть какое-нибудь логическое объяснение, почему в С++ отсутствуют операторы: ЕК> &&= ЕК> ||= ЕК> логическое XOR (^^ или что-то подобное) ЕК>Как-то несимметрично получается...
Что касается логического XOR, то его отсутствие объясняется одним принципиальным отличием операции XOR от операций AND и OR — он не допускает сокращенного вычисления. Без сокращенного вычисления логический XOR быть с известной долей осторожности заменен оператором '!='. XOR это фактически и ест логическое '!='.
А вот операторов '&&=' и '||=' действительно не хватает.
S> А сама функция должна внутри содержать неоходимые проверки флагов. Причём ситуация когда пишется:
S>
S> bool res = F1();
S> res = res && F2();
S> res = res || F3();
S>
S> Это уже плохо спланированная программа.
Поддержу предыдущего оратора:
в коде приведенном выше неясно как должны выполняться логические условия (здесь правда можно сказать что это сила привычки и т.д.):
if ((F1 && F2) || F3)
любому читающему будет понятен смысл данного утверждения. А о коде приведенном выше сказать однозначно нельзя какой смылс заложен в это условие.
Хотя иногда возникает необходимость раздробить условие на составные части (если он сильно длинное), но лично я все логические проверки провожу в блоке if (). Так для меня нагляднее и ясно читается мысль
S>Но скорее всего оно не находило поддержки по простой причине: люди (т.е. программисты) не склоны производить ВЫЧИСЛЕНИЯ с булевскими типами (ну какой прок скажем от операции bool + bool или bool — bool, что будет в результате?).
ВЫЧИСЛЕНИЯ над булевскими типами производятся постоянно, только операции для этого используются не + и -, а && || ! (а также "исключающее или" которого в С нет, но оно с успехом заменяется на сравнение булевских типов). Если же программист не склонен производить такие вычисления, то это свидетельствует о его недостаточной квалификации, значит ему следует выполнить 2...3 десятка упражнений на эту тему чтобы вычисления над булевскими типами стали для него столь же привычными как и над обычными числами.
Здравствуйте, SWW, Вы писали:
S>>Но скорее всего оно не находило поддержки по простой причине: люди (т.е. программисты) не склоны производить ВЫЧИСЛЕНИЯ с булевскими типами (ну какой прок скажем от операции bool + bool или bool — bool, что будет в результате?).
SWW>ВЫЧИСЛЕНИЯ над булевскими типами производятся постоянно, только операции для этого используются не + и -, а && || ! (а также "исключающее или" которого в С нет, но оно с успехом заменяется на сравнение булевских типов). Если же программист не склонен производить такие вычисления, то это свидетельствует о его недостаточной квалификации, значит ему следует выполнить 2...3 десятка упражнений на эту тему чтобы вычисления над булевскими типами стали для него столь же привычными как и над обычными числами.
Интересный вывод. Я польщен.
Re[6]: Операторы в С++
От:
Аноним
Дата:
11.06.03 07:25
Оценка:
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>Здравствуйте, Lorenzo_LAMAS, Вы писали:
S>>>Вы, батенька, логические операторы с побитовыми не путайте, для разных целей всё-таки.
L_L>>Так он не путает. Ему хочется &&= для переменных типа bool.
ЕК>Совершенно верно. И совершенно непонятно, почему для логических операторов нет сдвоенных с присваиванием. ЕК>Я жуе не говорю про логический xor. ЕК>Конечно, можно сделать ЕК>inline bool Xor(bool x1,bool x2) ЕК>{ ЕК> return (x1&&(!x2))||(x2&&(!x1)) ЕК>} ЕК>Но, согласитель, некрасиво. И вряд ли эффективно.
Могу предложить такой вариант...
inline bool xor(bool a, bool b)
{
return a != b;
}
или
inline bool xor(int a, int b)
{
return !!a != !!b;
}
Здравствуйте, SergeyS, Вы писали:
SS>Здравствуйте, Евгений Коробко, Вы писали:
ЕК>>Я жуе не говорю про логический xor. ЕК>>Конечно, можно сделать ЕК>>inline bool Xor(bool x1,bool x2) ЕК>>{ ЕК>> return (x1&&(!x2))||(x2&&(!x1)) ЕК>>} ЕК>>Но, согласитель, некрасиво. И вряд ли эффективно.
SS>Логический xor — это оператор != SS>Xor = x1!=x2
Я бы предпочел написать
BOOL x1, x2;
{...}
BOOL bTest = ( (x1!=0) ^ (x2!=0) );
BOOL bTest = ( (!x1) ^ (!x2) );
хотя все равно убого. Надо спросить у Страуструпа, почему нет ^^ . Давайте спросим?
Здравствуйте, SWW, Вы писали:
Д>>А как насчет этого Д>>
Д>>inline bool xor(int a, int b)
Д>>{
Д>> return !!a != !!b;
Д>>}
Д>>
SWW>Раз пошла такая пьянка, то можно и проще: SWW>
SWW>inline bool xor(int a, int b)
SWW>{
SWW> return !a != !b;
SWW>}
SWW>
Ну пьянка или нет, я хотел показать, как BOOL(и не только BOOL) можно преобразовать к bool,
а с точки зрения оптимальности твое лучше. Хотя я не знаю, как все это дело компилер обрабатывает...
Не все в этом мире можно выразить с помощью нулей и единиц...
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>А для чего, если не секрет, они Вам нужны? С примерами пожалуйста.
ЕК>Странный вопрос. Каждый бинарный оператор имеет соответствующий оператор с присваиванием. Исключение составляет лишь логические операторы || и &&. ЕК>Логическое XOR — это, по-моему, вообще очевидно. ЕК>Пример:
ЕК>bool res=true; ЕК>for(int i=0;i<Size;i++) res&&=test_object(objs[i]);
ЕК>Устроит?
ЕК>Эти операторы (|| и &&) нужны для того же, для чего и +=,-=,*=,/=,<<=,>>=,&=,|=,^=. Для большей эстетичности, читаемости и оптимизации.
ЕК>Убедил?
Бред какой-то...
Зачем проболжать вычесления, если res обнулился?
Тем более, что test_object(objs[i]) может быть достаточно трудоемкой.
Я на практике никода не встречался с такой ситуацией, что нужен этот оператор...
Не все в этом мире можно выразить с помощью нулей и единиц...
S> А сама функция должна внутри содержать неоходимые проверки флагов. Причём ситуация когда пишется:
S>
S> bool res = F1();
S> res = res && F2();
S> res = res || F3();
S>
S> Это уже плохо спланированная программа.
Интересный способ доказательства: придумать заведомо бесполезный пример и, убедительно доказав его бесполезность, сделать вывод о бесполезности операторов ||= и &&=
Вообще-то значение res может понадобиться после первой строки, но до второй.
Оператор != не подходит потому, что в С++ есть неявное преобразование из int в bool.
Отличие xor от bool должно быть в том, что xor принудительно приводит операнды к bool.
int a=2,b=4;
a xor b == false (a и b приводятся к true)
a!=b == true
Т.е.
#define xor(a,b) (static cast<bool>(a)!=static cast<bool>(b))
Но хотелось бы в форме оператора.
Ну и опять-таки, ^^=...
А про то, что можно обойтись условными операторами и пр. — когда можно, а когда и нет. Знаете, есть дискретная математика, всякие так КНФ, ДНФ и пр. самые настоящие вычисления, только не с числами, а с булевскими переменными.
Здравствуйте, Stepkh, Вы писали:
S>любому читающему будет понятен смысл данного утверждения. А о коде приведенном выше сказать однозначно нельзя какой смылс заложен в это условие. S>Хотя иногда возникает необходимость раздробить условие на составные части (если он сильно длинное), но лично я все логические проверки провожу в блоке if (). Так для меня нагляднее и ясно читается мысль
А что если нам это нужно для хранения успешности выполнения операций?
в этом коде:
if ((F1() && F2()) || F3())
Не будет выполненна F2 если F1 возвратит 0 , и не будет выполнена F3 если 1 возвратят F1 и F2 , а в коде:
bool res = F1();
res = F2() && res;
res = F3() || res;
Д>Ведь новый шаг делается, при условии, что все предыдущие вызовы test() были верными.
Д>Или в крайнем случае можно поставить if() Д>А для того, чтобы проверить сохранить результат можно пользоваться так: Д>
Д>res = i == size;
Д>
Использование переменной цикла после цикла — не совсем хорошо.
Впрочем, возможно, это действительно не самый лучший пример.
Здравствуйте, Аноним, Вы писали:
А>Могу предложить такой вариант... А>
А>inline bool xor(bool a, bool b)
А>{
А> return a != b;
А>}
А>
А>или А>
А>inline bool xor(int a, int b)
А>{
А> return !!a != !!b;
А>}
А>
Конечно, можно. Вопрос в том, почему этого нет в С++. Мне кажется, что былобы очень логично. И не водно ни одного аргумента против таких операторов. Это как если бы long не мог быть unsigned или нельзя было бы делать указатели на double... Вот почему нет оператора возведения в степерь (**) — понятно. Понятно, почему нельзя перегружать оператор точка (.) и нельзя добавлять новые операторы. А вот отсутствие оператора логического xor и операторов &&= и ||= непонятно. Они нужны хотя бы для симметрии.
Можно вообще класс написать
class Bool
{
...
};
и в нём перегрузить все операторы а также &=,|=,^=, сделать конструкторы и оператор преобразования к bool.
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>Использование переменной цикла после цикла — не совсем хорошо.
Нет это совсем плохо ибо запрещено стандартом.
... << RSDN@Home 1.0 beta 6a >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Евгений Коробко, Вы писали:
ЕК>>Использование переменной цикла после цикла — не совсем хорошо. WH>Нет это совсем плохо ибо запрещено стандартом.
Да возможно... Но я лично пользуюсь VS 6.0, и Microsoft считает, что для совместимости
этот пункт можно обойти...
Не все в этом мире можно выразить с помощью нулей и единиц...
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>Оператор != не подходит потому, что в С++ есть неявное преобразование из int в bool. ЕК>Отличие xor от bool должно быть в том, что xor принудительно приводит операнды к bool.
ЕК>int a=2,b=4;
ЕК>a xor b == false (a и b приводятся к true) ЕК>a!=b == true
ЕК>Т.е. ЕК>#define xor(a,b) (static cast<bool>(a)!=static cast<bool>(b))
ЕК>Но хотелось бы в форме оператора. ЕК>Ну и опять-таки, ^^=...
ЕК>А про то, что можно обойтись условными операторами и пр. — когда можно, а когда и нет. Знаете, есть дискретная математика, всякие так КНФ, ДНФ и пр. самые настоящие вычисления, только не с числами, а с булевскими переменными.
Да, но я не предлагаю сравнивать на неравенство два целых числа.
Я в своем примере писал !!а.
А если говорить о красивости... Не так часто сравниваются два логических выражния на равенство или неравенство, тем более, если имеет место неявное преобразование типов.
Не все в этом мире можно выразить с помощью нулей и единиц...
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>отсутствие оператора логического xor и операторов &&= и ||= непонятно. Они нужны хотя бы для симметрии.
ЕК>Можно вообще класс написать ЕК>class Bool ЕК>{ ЕК>... ЕК>}; ЕК>и в нём перегрузить все операторы а также &=,|=,^=, сделать конструкторы и оператор преобразования к bool.
Забавно, конечно, создавать класс Bool, но это всего лишь еще один новый "велосипед"...
Гораздо проще обойтись и обычными операторами.
А симметрия, наверное нарушена. Но я не знаю никого, кто бы от этого пострадал...
Если так судить, то и штрих Шеффера надо добавлять и стрелку Пирса...
Они все легко заменяемы.
Удалено избыточное цитирование. -- ПК.
Не все в этом мире можно выразить с помощью нулей и единиц...
Д>>А симметрия, наверное нарушена. Но я не знаю никого, кто бы от этого пострадал...
Да, собственно, изначально вопрос был не в том, как обойтись без этих операторов (это очевидно).
Вопрос был в том, а почему, собственно, их нет. Лично мне их отсутствие кажется нелогичным.
Здравствуйте, Евгений Коробко, Вы писали:
ЕК>Да, собственно, изначально вопрос был не в том, как обойтись без этих операторов (это очевидно). ЕК>Вопрос был в том, а почему, собственно, их нет. Лично мне их отсутствие кажется нелогичным.
нелогическим
насколько я помню,самая моя первая программа нуждалась именно в ^^ и ^^=