Смущает использование оператора двойного логического «НЕ» (!!)

У меня есть код на C ++, в котором широко используется !!. Я немного сбит с толку, потому что, насколько я знаю, !! - это не оператор сам по себе, а два ! друг за другом. Это будет означать, что !!foo то же самое, что просто foo.

Есть ли место и / или причина, по которой !! действительно имеет смысл? Я думал о том, может ли это иметь немного мудрое значение? Итак, вы сначала выполняете некоторую побитовую операцию с foo, а затем ! с результатом? Но я, кажется, не помню, чтобы ! использовался как немного мудрый оператор, и, кажется, не нашел ни одной ссылки, говорящей мне, что это тоже. Насколько я могу судить, ! используется только как логический оператор, и в этом случае

!!foo == foo


person inquam    schedule 24.04.2013    source источник
comment
Еще можно написать x+++++y+1, но это плохая идея.   -  person msw    schedule 24.04.2013
comment
@GrahamBorland Теперь я пойду и проголосую за это как за дубликат этого.   -  person Alvin Wong    schedule 24.04.2013
comment
Вы также можете прочитать это: что есть !! в c?.   -  person Grijesh Chauhan    schedule 24.04.2013
comment
@msw нет, не можешь. изменение более одного раза между двумя точками последовательности является неопределенным поведением. !! прекрасно определен и соответствует запуску безопасных операторов преобразования типа bool. Что особенно полезно для optional, variant или любого умного указателя.   -  person v.oddou    schedule 10.12.2019


Ответы (5)


Это не так просто, как двойное отрицание. Например, если у вас есть x == 5, а потом примените два! операторов (!!x), он станет 1 - таким образом, он используется для нормализации логических значений в диапазоне {0, 1}.

Обратите внимание, что вы можете использовать ноль как логическое значение false и ненулевое значение для логического значения true, но вам может потребоваться нормализовать результат до 0 или 1, и это когда !! полезно.

Это то же самое, что и x != 0 ? 1 : 0.

Кроме того, обратите внимание, что это будет неверно, если foo не входит в {0, 1} набор:

!!foo == foo

#include <iostream>

using namespace std;

int main()
{
        int foo = 5;

        if(foo == !!foo)
        {
                cout << "foo == !!foo" << endl;
        }
        else
        {
                cout << "foo != !!foo" << endl;
        }



        return 0;
}

Печатает foo != !!foo.

person Nemanja Boric    schedule 24.04.2013
comment
каковы могут быть возможные варианты использования для этого? - person Koushik Shetty; 24.04.2013
comment
Скажем, у вас есть место, где bool хранится как 1 или 0, в bit или что-то в этом роде. И значение, которое вы проверяете, равно 5 (что будет считаться истинным), вы можете в основном превратить это 5 в 1. - person inquam; 24.04.2013
comment
логический х =! 0; // true bool x =! -15 // false int i = x; Проверь это - person mtsiakiris; 24.04.2013
comment
Если говорить более формально, результат будет true. Значения типа bool: true и false. В арифметическом контексте они преобразуются в 1 и 0 соответственно. - person Pete Becker; 24.04.2013
comment
Я использовал эту технику на компиляторе, который жаловался, когда я неявно приводил int к bool (предупреждение о производительности: значение будет преобразовано в 0 или 1). Мои варианты - сделать bool преобразование в стиле C (что я считаю плохой привычкой), сделать 0 != v (?1:0 впоследствии становится избыточным), что создает неоднозначность порядка операций, вынуждая ()ing (по крайней мере, чтобы было понятно, что происходит) , или static_cast<bool>( v ), что слишком многословно. !! приводит к типу, который неявно преобразуется в bool в bool без предупреждений и как унарный (и, следовательно, строго связанный) оператор. - person Yakk - Adam Nevraumont; 24.04.2013

Его можно использовать как сокращение для преобразования foo в логическое выражение. По какой-то причине вы можете захотеть превратить небулево выражение в истинное или ложное исключительно.

foo = !!foo превратит foo в 1, если он не равен нулю, и оставит его на 0, если он уже есть.

person Victor Sand    schedule 24.04.2013

если foo != 0, то !!foo == 1. По сути, это уловка для преобразования в bool.

person Avidan Borisov    schedule 24.04.2013
comment
1 не bool. Это int. - person Kerrek SB; 24.04.2013
comment
@Kerrek SB Я знаю, я имею в виду реальную стоимость. - person Avidan Borisov; 24.04.2013

Если foo не относится к типу bool, то !!foo будет. Итак, !!foo может быть 1 или 0.

person Tobias Müller    schedule 24.04.2013
comment
0 и 1 - это ints, а не bools. Здесь мы говорим о C ++; может вы это путаете с C? - person Kerrek SB; 24.04.2013
comment
Ты прав. Я должен был сказать правду или ложь. :) - person Tobias Müller; 24.04.2013

Этот метод используется для безопасной оценки переменной в логическом контексте. Если у вас есть нормальный диалог с bool (operator bool()), несвязанные переменные (с разными типами) могут нежелательным образом участвовать в логических выражениях. Реализовано определение operator!, которое возвращает отрицательное логическое значение. И его результат снова нужно отрицать. Просто ознакомьтесь с идиомой Safe bool.

person Jan Herrmann    schedule 24.04.2013