basic_ostream для указателей существует несколько перегрузок operator<<.
Часть из этих перегрузок выполнена в качестве функций-членов класса, а часть как внешние функции.
В определении самого класса для указательных типов имеется только перегрузка для параметра типа void *
template<class charT, class traits = char_traits<charT>>
class basic_ostream : virtual public basic_ios<charT, traits> {
public:
...
basic_ostream<charT, traits>& operator<<(const void* p);
...
};
При вызове
cout.operator<<("Hello");
вызывается именно функция-член класса, а других подходящих вариантов перегрузки нет:
"Hello" - массив char[6], который может быть неявно преобразован в char const *, который в свою очередь преобразуется в void const * поэтому и выводится адрес, в соответствии с поведением данной перегрузки.
Перегрузки, принимающие char const * объявлены как внешние функции:
template<class charT, class traits>
basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, const char*);
template<class traits>
basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char*);
В коде
operator<<(cout, "Hello");
явно вызывается внешняя функция operator<<, поэтому функции-члены basic_ostream даже не рассматриваются. Естественно, это приводит к выводу строки в соответствии с поведением перегрузки для char const *
Код
cout << "Hello";
приводит к рассмотрению перегрузок operator<< объявленных как функции-члены basic_ostream, и как внешних функций.
При выборе соответствующих перегрузок, перегрузка с параметром char const * оказывается более подходящей, чем остальные, поэтому выбирается соответствующая внешняя операторная функция.