Двойное отрицание в коде C++

116
задан Mateen Ulhaq 23 October 2011 в 04:09
поделиться

10 ответов

Это - прием для преобразования в bool.

114
ответ дан Don Neufeld 24 November 2019 в 02:14
поделиться

Это - на самом деле очень полезная идиома в некоторых контекстах. Возьмите их макросы (пример от ядра Linux). Для GCC они реализованы следующим образом:

#define likely(cond)   (__builtin_expect(!!(cond), 1))
#define unlikely(cond) (__builtin_expect(!!(cond), 0))

, Почему они должны сделать это? GCC's __builtin_expect обработки его параметры как long а не bool, так должна быть некоторая форма преобразования. Так как они не знают то, что cond, когда они пишут тем макросы, это является самым общим для простого использования !! идиома.

Они могли, вероятно, сделать то же самое путем сравнения с 0, но по-моему, это на самом деле более просто, чтобы сделать двойное отрицание, так как это является самым близким к cast-to-bool, который имеет C.

Этот код может использоваться в C++ также..., это - вещь наименьшего общего знаменателя. Если возможно, сделайте что работы и в C и в C++.

69
ответ дан Tom Barta 24 November 2019 в 02:14
поделиться

Кодеры думают, что это преобразует операнд в bool, но потому что операнды & & уже неявно преобразовываются в bool, это совершенно избыточно.

50
ответ дан fizzer 24 November 2019 в 02:14
поделиться

Да это корректно, и не Вы не пропускаете что-то. !! преобразование в bool. См. этот вопрос для большего количества обсуждения.

11
ответ дан Community 24 November 2019 в 02:14
поделиться

Это - техника, чтобы не писать (переменная! = 0) - т.е. преобразовать из любого типа это к bool.

Код IMO как это не имеет никакого места в системах, которые должны быть обслужены - потому что это не сразу читаемый код (следовательно вопрос во-первых).

Код должен быть четким - иначе Вы оставляете наследие долга времени для будущего - поскольку это занимает время для понимания чего-то, что является напрасно замысловатым.

11
ответ дан Richard Harrison 24 November 2019 в 02:14
поделиться

Это обходит предупреждение компилятора. Попробуйте это:

int _tmain(int argc, _TCHAR* argv[])
{
    int foo = 5;
    bool bar = foo;
    bool baz = !!foo;
    return 0;
}

строка 'панели' генерирует "значение принуждения к bool, 'верному' или 'ложному' (производительность, предупреждающая)" на MSVC ++, но 'baz' подхалимы строки через штраф.

9
ответ дан RobH 24 November 2019 в 02:14
поделиться

Оператор Is! перегруженный?
В противном случае они, вероятно, делают это для преобразования переменной в bool, не производя предупреждение. Это - определенно не стандартный способ сделать вещи.

5
ответ дан Marcin 24 November 2019 в 02:14
поделиться

Как упомянутый Marcin, могло бы хорошо иметь значение, если перегрузка оператора находится в игре. Иначе в C/C++ не имеет значения кроме того, если Вы делаете одну из следующих вещей:

  • прямое сравнение с true (или в C что-то как TRUE макрос), который является почти всегда плохой идеей. Например:

    if (api.lookup("some-string") == true) {...}

  • Вы просто хотите что-то преобразованное в строгое значение 0/1. В C++ присвоение на bool сделает это неявно (для тех вещей, которые неявно конвертируемы к bool). В C или если Вы имеете дело с non-bool переменной, это - идиома, которую я видел, но я предпочитаю (some_variable != 0) разнообразие сам.

я думаю в контексте большего булева выражения, он просто загромождает вещи.

1
ответ дан Community 24 November 2019 в 02:14
поделиться

Это корректно, но, в C, бессмысленно здесь - 'если' и '& &'; рассматривал бы выражение тот же путь без'!!'.

причина сделать это в C++, я предполагаю, является этим '& &'; мог быть перегружен. Но тогда, так мог'!', таким образом, это не делает действительно гарантия, Вы получаете bool, не смотря на код для типов variable и api.call. Возможно, кто-то с большим опытом C++ мог объяснить; возможно, это предназначено как вид защиты подробно меры, не гарантия.

0
ответ дан Darius Bacon 24 November 2019 в 02:14
поделиться

Возможно, программисты думали что-то вроде этого...

!! myAnswer является булевской переменной. В контексте это должно стать булевской переменной, но я просто люблю ударять по вещам удара удостовериться, потому что когда-то давно была таинственная ошибка, которая укусила меня и удар удара, я уничтожил его.

0
ответ дан dongilmore 24 November 2019 в 02:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: