Преобразование false в тип указателя void *?

Может кто-нибудь объяснить мне, что здесь происходит?

У меня был этот код:

#include <fstream>
#include <string>
#include <iostream> 
int main(){   
    std::ifstream file("test.txt");    
    std::string x;
    while (true) { 
        if (!(file >> x)) return 0;
        std::cout << x << "\n";   
    }
}

... компилирует отлично, делает то, что он должен делать, пока не проблема. Иногда мне так не нравится !, потому что его можно легко пропустить, поэтому я заменил if на

if ((file >> x)==false) return 0;  

.. и вдруг мой компилятор (gcc 4.8.5) жалуется на предупреждение:

 warning: converting ‘false’ to pointer type ‘void*’ [-Wconversion-null]
     if ((file >> x)==false) return 0;

и именно здесь я начинаю озадачиваться. Откуда приходит void*? Не возвращает >> ссылку, которая должна быть отправлена ​​на bool? Почему false преобразован в void*? Почему не срабатывает такое же предупреждение, когда я явно не пишу false?

Из любопытства я также пробовал это:

if ((file>>x)==true) return 0;

который вызывает бурю ошибок, начиная с

error: no match for ‘operator==’ (operand types are ‘std::basic_istream<char>’ and ‘bool’)
 if ((file>>x)==true) return 0;
              ^

и теперь я полностью потерян. Как false отличается от bool чем true? Конечно, разные значения, но я всегда думал, что true и false имеют один и тот же тип.

Ответ 1

Вспомним, что С++ имеет перегрузки оператора. В частности, std::basic_istream перегружает operator!.

Увы, не существует принуждения, что перегрузки операторов семантически согласованы, поэтому для == нет перегрузки между istream и a bool. Таким образом, сравнение с true не выполняется. Однако компилятору также разрешено применять неявные преобразования, чтобы скомпилировать выражение - в этом случае false может быть неявно преобразован в нулевой указатель, а basic_istream имеет перегрузка operator void* (хотя, по-видимому, это было заменено на operator bool на С++ 11 - для исправления несогласованности).