Определение двойного восклицания?

Я понимаю, что делает двойной восклицательный знак (или я думаю, что понимаю), но я не уверен, как он определен для случайного объекта. Например, во фрагменте кода ниже:

Assignment *a;
if (!getAssignment(query, a))
   return false;
hasSolution = !!a;

if (!a)
   return true;

Как мне узнать, к какому значению приведет двойной восклицательный знак? Другими словами, всегда ли это превращается в истину? ложный ? или вы можете определить поведение для него, например, выполнить метод для определения результата (как объект знает, как действовать в этой ситуации)? Я немного озадачен этим фрагментом кода из-за всего этого восклицательного материала. Любое объяснение приветствуется.

Надеюсь, я был ясен и спасибо.

 Konrad Rudolph07 июл. 2012 г., 14:49
!! в C ++ это анти-паттерн, вот и все.
 ildjarn07 июл. 2012 г., 17:42
@ Конрад: я не согласен - это не анти-паттерн, это паттерн, который допускает только перегрузкуoperator! вместо обоихoperator! а такжеoperator bool (или какая-то идиома безопасного булла).
 Konrad Rudolph07 июл. 2012 г., 22:49
@ildjarn Вы должны использовать очевидный код. Ни актеры, ни актеры!! Является ли это. Сравните явно вместо использования неявного принуждения (что в последнем случае является слабой типизацией). использованиеa != nullptr.
 ildjarn07 июл. 2012 г., 21:34
@ Конрад: Вы говорите, анти-шаблон, я говорю идиома сама по себе. Ваша неприязнь к!! не делает это "дерьмом". Хотите избежать предупреждения C4305 в VC ++? Ты можешь использоватьstatic_cast или же!! - что легче набирать и читать?
 Konrad Rudolph07 июл. 2012 г., 17:54
@ildjarn Как это делает это не анти-паттерном?Do перегружать логический оператор, когда это имеет смысл. И когда это не так, не перегружайтеoperator! или. Они приходят парами. Исключительно.

Ответы на вопрос(7)

о 1 и a == 0 до 0. Который находится в логическом контексте (то есть C ++) true или false.

думайте о нем как о двух отдельных операторах, один из которых работает на результат другого.

Для всех примитивных типов это будет «работать».!a эквивалентноa == 0, так!!a эквивалентно!(a == 0)что в свою очередь эквивалентноa != 0.

Для пользовательских типов он не будет компилироваться, если они не перегруженыoperator !, Но очевидно, что в этом случае поведение может быть практически любым.

getAssigment метод успешен, и является ли назначенный указатель ненулевым.

Код проверяет, хотя и в запутанном виде, используя слабую типизацию, вместо того, чтобы пытаться охватить явность и C ++ & # x2019; сильная типизация. Как следствие, это не идиоматический язык C ++, и его сложнее понять, чем необходимо.

В частности, не пользуйтесь!!a в C ++. Это устоявшаяся идиома в слабо типизированных языках, таких как JavaScript, для приведения значения в логический тип. Но в C ++ этоnot обычно используется.

Пока неясно, что делает код, посколькуhasSolution не определено или не используется. Однако яsuspect что код должен быть эквивалентен следующему:

Assignment *a;
return getAssignment(query, a) and a == nullptr;

(До C ++ 11 нужно написать0 вместоnullptr.)

Тем не менее, этот код все еще показывает плохой дизайн: почемуa передается по ссылке? Почему это не возвращаемое значение? Хуже,a никогда не используется, так ненужно. Еслиa это действительно не нужно, его следует полностью исключить. Если это необходимо, это должно быть возвращаемое значение. Другими словами, прототипgetAssignment должно быть следующим:

Assignment* getAssignment(the_type_of_query query);

И это следует использовать просто следующим образом:

Assignment* a = getAssignment(query);

Кроме того, я подозреваю, что этот код фактически присваивает владение памятью необработанному указателюa, Этонастоятельно не рекомендуется в современном C ++. Либо не используйте указатели, ни умный указатель.

!! не является единственным токеном в C ++ и просто разрешает применение! оператор дважды.

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

Второе применение! просто сводит на нет результат первого!.

Выражение!!a эквивалентноa != 0.

!! & quot; оператор, поэтому на самом деле оператор эквивалентен:

hasSolution =! (! a);

Итак, сначала оператор! () Вызывается для выражения "a", затем вызывается другой оператор! () Для результата. В случае нашего кода "a" это указатель на Назначение. C ++ определяет особый случай использования оператора! () Для типа указателя: он возвращает bool, который имеет значение true, если указатель равен нулю, и false в противном случае. Короче говоря, тоже самое, что и выражение (a == 0). Вызов оператора! () Для результата (! A), который является логическим значением, просто возвращает результат, то есть возвращает true, если (! A) равно false, и false, если (! A) - true.

Итак, в заключение, (!! a) возвращает тот же результат, что и (a! = 0). Это потому, что "а" это указатель

Решение Вопроса

a это указатель В C ++nullptr определяется как недопустимый указатель.!pointer превращаетnullptr указатель наtrue и неnullptr указатель наfalse. !boolean виткиtrue вfalse а такжеfalse вtrue, Это всегда будет работать.

!(!a) это полезный способ думать об этом.

 07 июл. 2012 г., 20:59
NULL НЕ определен как недопустимый указатель, он определен как ложный в логическом контексте. a = NULL; совершенно законно. Самый простой способ запомнить !! a - сузить a = 0 до 1 и a == 0 до 0.
 07 июл. 2012 г., 14:45
Я изменил 0 на NULL, чтобы избежать некоторой распространенной путаницы, что указатель NULL должен иметь двоичное значение 0 (нет, целочисленная константа 0 неявно преобразуется в указатель NULL, но нет гарантии на представление NULL)
 08 июл. 2012 г., 02:06
Использование 0 для канонического неверного указателя допустимо в C ++ и исторически использовалось как стандарт. NULL - это артефакт из C, который поддерживается только как часть совместимости со стандартной библиотекой C.It was not recommended to use NULL within C++, Чтобы избежать ненужного аргумента, я переключу его наnullptr который является ключевым словом в C ++ 11.
bool result = true; 
result = !!result; // result = true, e.g. !result is false, !!result is !false.

Ваш ответ на вопрос