Поведение вашего кода не указано согласно стандарту C ++.
Объяснение
следующее (я удалил std::endl
для простоты)
std::cout << "Hello, world!" << print( std::cout );
эквивалентно этому:
operator<<(operator<<(std::cout, "Hello, World!"), print(std::cout));
, который является вызовом функции, передавая два аргумента:
- Первый аргумент:
operator<<(std::cout, "Hello, World!")
- Второй аргумент:
print(std::cout)
Теперь Стандарт не определяет порядок, в котором оцениваются аргументы. не указано . Но ваш компилятор, кажется, сначала оценивает второй аргумент, поэтому он сначала печатает «Как дела?» , оценивая второй аргумент в значение типа std::ostream&
, которое затем передается показанному вызову выше (этим значением является сам объект std::cout
).
Почему шестнадцатеричный вывод?
Вы получаете шестнадцатеричный вывод, потому что второй аргумент оценивается как std::cout
, который печатается как шестнадцатеричное число, поскольку std::cout
неявно преобразуется в значение указателя типа void*
, поэтому он печатается как шестнадцатеричное число.
Попробуйте это:
void const *pointer = std::cout; //implicitly converts into pointer type!
std::cout << std::cout << std::endl;
std::cout << pointer << std::endl;
Будет напечатано одинаковое значение для обоих. Например, этот пример на ideone печатает это:
0x804a044
0x804a044
Также обратите внимание, что я не использовал явное приведение; скорее std::cout
неявно преобразуется в тип указателя.
Надеюсь, это поможет.
Как правильно написать функцию, которая вставляет данные в ostream
, но может также связываться с operator<<
?
Когда это зависит от того, что вы подразумеваете под цепочкой? Очевидно, что следующее не будет работать (как объяснено выше):
std::cout << X << print(std::cout) << Y << Z; //unspecified behaviour!
Независимо от того, как вы пишете print()
.
Однако это четко определено:
print(std::cout) << X << Y << Z; //well-defined behaviour!