Почему явно вызывающий оператор << на 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
не привело бы меня к мысли, что это приведет к какому-либо другому поведению; также учитывая тот факт, что явно вызов операторной функции не имеет значения (или должен быть как минимум).
Так почему я получаю этот вывод? Почему я получаю адрес вместо самой строки при вызове оператора явно? Это даже адрес в памяти или просто вывоз мусора? Любые ответы приветствуются.
Ответы
Ответ 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!");
На самом деле печатает строку.
Надеюсь, это поможет!