При размышлении об этом может помочь трансляция между синтаксисом оператора «<<» и синтаксисом функции «operator <<». Ваш пример C ++ эквивалентен этому фрагменту кода C ++: </p>
operator<< ( operator<< (cout, "Hello World!"), endl);
Первое, что вы должны здесь заметить, это то, что на самом деле в cout не так много хитрости. Что умно, так это функция operator <<, в частности, версия функции operator <<, которая принимает потоковый объект (то есть, что такое cout, но и многие другие тоже) в качестве первого аргумента. Или, точнее, диапазон функций operator <<, которые принимают объект потока в качестве первого аргумента и принимают конкретную вещь в качестве второго аргумента - есть один для каждого типа объекта, который вы можете поместить в поток cout. Вы также можете увидеть один из приемов C ++ в этом синтаксисе; Функции оператора << на объектах потока всегда возвращают объект потока, который им был передан, тем самым позволяя создавать цепочки такого типа. </p>
Чтобы поместить код C ++ в компоновщики и системные ABI, которые ожидают синтаксиса C-подобных функций, большинство компиляторов C ++ "манипулируют" именами функций, чтобы закодировать в них тип аргументов, которые они имеют. (Также, конечно, «<<» не является допустимым именем C-подобной функции.) Итак, если вы посмотрите на сгенерированную сборку для этого бита функции, вы увидите, что имена двух функций были отличаются друг от друга - они будут иметь суффиксы, указывающие типы аргументов. Вы можете сделать что-то подобное вручную: </p>
operator_lshift__stream__endl(
operator_lshift__stream__string(cout, "Hello World!"), endl);
И там у вас есть кое-что, что вы можете реализовать в C.