Подтвердить что ты не робот

Почему явно вызывающий оператор << на std:: cout вызывает неожиданный вывод?

Мне было просто интересно, что произойдет, если я вызову operator<< в std::cout явно, потому что узнал, что a.operator() точно такой же, как a(). Поэтому я делаю это и печатает что-то странное:

#include <iostream>

using std::cout;

int main()
{
    cout.operator<<("Hello World");
}

Output: 0x80486a0

Как ни странно, он выдает адрес (адрес может отличаться для вас, но он все равно должен быть адресом). Я думаю, что это адрес строки, поэтому я пытаюсь разыменовать ее, чтобы заставить ее выводить строку:

*( cout.operator<<("Hello World") );

Но я получаю очень длинную ошибку

no match for operator* in '*std::cout.std::basic_ostream<...

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

Так почему я получаю этот вывод? Почему я получаю адрес вместо самой строки при вызове оператора явно? Это даже адрес в памяти или просто вывоз мусора? Любые ответы приветствуются.

4b9b3361

Ответ 1

Оператор вывода для встроенных строк, т.е. при принятии аргумента char const* в качестве аргумента, не является членом std::ostream. Оператор, принимающий char const*, является функцией, не являющейся членом, будет называться

operator<< (std::cout, "Hello World");

Однако существует элемент, принимающий void const*, который форматирует значение указателя с использованием шестнадцатеричной нотации. Этот член является лучшим совпадением при явной передаче любого указателя члену operator<< () из std::ostream.

Разыменование результатов operator<<() не работает: операторы возвращают a std::ostream&, у которого нет унарного operator*() перегруженного. Если вы хотите разыграть аргумент, вы бы назвали его так:

std:cout.operator<< (*"Hello World");

Однако это будет просто отличать char const*, строковый литерал распадается на, давая индивидуальный символ H. Функция вывода символа также не является функцией-членом, в то время как операторы вывода для целых чисел, т.е. Печатают значение символа H. Для системы, использующей ASCII, это будет 72.

Ответ 2

Я думаю, что проблема здесь в том, что operator <<, который печатает строку C-стиля в выходном потоке, на самом деле является свободной функцией, а не функцией-членом basic_ostream. Однако basic_ostream имеет функцию operator<<, которая принимает void* и выводит ее адрес. В результате, если вы явно пытаетесь вызвать operator<< как функцию-член, вы вызываете версию, которая выводит адрес строки C-стиля, а не бесплатную функцию, которая выводит символы на строку.

Вы можете увидеть это, позвонив

operator<< (std::cout, "Hello, world!");

На самом деле печатает строку.

Надеюсь, это поможет!