Wie wird "std :: cout << std :: endl;" kompiliert?
Die meistenIO Stream-Manipulatoren sind reguläre Funktionen mit folgender Signatur:
std::ios_base& func( std::ios_base& str );
Allerdings einige Manipulatoren (einschließlich der am häufigsten verwendeten -std::endl
undstd::flush
) sind Vorlagen der folgenden Form:
template< class CharT, class Traits >
std::basic_ostream<CharT, Traits>& func(std::basic_ostream<CharT, Traits>& os);
Then, wie funktioniert die Zusammenstellung vonstd::cout << std::endl;
erfolgreich, vorausgesetzt, das folgende Beispiel schlägt fehl:
$ cat main.cpp
#include <iostream>
int main()
{
auto myendl = std::endl;
std::cout << myendl;
}
$ g++ -std=c++11 main.cpp -o main
main.cpp: In function ‘int main()’:
main.cpp:5:24: error: unable to deduce ‘auto’ from ‘std::endl’
auto myendl = std::endl;
^
s ist klar, dass der Kontext (instd::cout << std::endl;
) hilft dem Compiler, den Verweis auf @ zu disambiguierstd::endl
. Aber nach welchen Regeln wird dieses Verfahren durchgeführt? Es sieht aus wie eine echte Herausforderung für die Überlastung der Auflösung, die zwei Fragen gleichzeitig beantworten muss:
std::endl<CharT, Traits>()
doesstd::endl
beziehen aufWelche Funktion hat dasoperator<<
beziehen aufDer Abzug von Vorlagenargumenten (1) sollte vor der Überladungsauflösung (2) erfolgen, aber es scheint, dass (zumindest ein Teil von) (2) ausgeführt werden muss, damit (1) erfolgreich ist.
Etwas verwandte, aber keine doppelten Fragen sind:
Funktioniert std :: endl sowohl mit cout als auch mit wcout?Warum kompiliert endl (std :: cout)Wie funktioniert std :: flush?Keine dieser Fragen und keine der Antworten auf diese Fragen befassen sich mit der Funktionsweise der Argumentableitung für Vorlagen, die der Überladungsauflösung vorausgehen sollte, von dieser jedoch unterstützt werden muss.
Zusatzfrage Wie funktioniert die Überladungsauflösung, wenn ein Argument eine überladene Funktion ist?