Разработчики Legacy C не имели логического типа, поэтому они часто #define TRUE 1
и #define FALSE 0
, а затем использовали произвольные числовые типы данных для логических сравнений. Теперь, когда у нас есть bool
, многие компиляторы будут выдавать предупреждения, когда определенные типы назначений и сравнений выполняются с использованием комбинации числовых типов и логических типов. Эти два использования в конечном итоге столкнутся при работе с устаревшим кодом.
Чтобы обойти эту проблему, некоторые разработчики используют следующую логическую идентификацию: !num_value
возвращает bool true
if num_value == 0
; false
в противном случае. !!num_value
возвращает bool false
, если num_value == 0
; true
в противном случае. Одного отрицания достаточно для преобразования num_value
в bool
; однако двойное отрицание необходимо для восстановления первоначального смысла булева выражения.
Этот шаблон известен как идиома , то есть то, что обычно используется людьми, знакомыми с языком. Поэтому я не вижу в этом анти-паттерна, так как я бы static_cast<bool>(num_value)
. Приведение может очень хорошо дать правильные результаты, но некоторые компиляторы выдают предупреждение о производительности, поэтому вам все равно придется учесть это.
Другой способ решения этой проблемы - сказать (num_value != FALSE)
. Я тоже с этим согласен, но в целом, !!num_value
гораздо менее многословен, может быть более ясным и не смущает, когда вы его видите во второй раз.