¿Cómo se compila "std :: cout << std :: endl;"?

MásManipuladores de flujo IO son funciones regulares con la siguiente firma:

std::ios_base& func( std::ios_base& str );

Sin embargo, algunos manipuladores (incluidos los más utilizados)std::endl ystd::flush) son plantillas de la siguiente forma:

template< class CharT, class Traits >
std::basic_ostream<CharT, Traits>& func(std::basic_ostream<CharT, Traits>& os);

Entonces, ¿cómo funciona la compilación destd::cout << std::endl; tener éxito dado que el siguiente ejemplo falla:

$ 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;
                        ^

Está claro que el contexto (enstd::cout << std::endl;) ayuda al compilador a desambiguar la referencia astd::endl. Pero, ¿cuáles son las reglas que rigen ese procedimiento? Parece un verdadero desafío para la resolución de sobrecarga, que tiene que responder dos preguntas a la vez:

¿Qué especialización destd::endl<CharT, Traits>() hacestd::endl ¿Referirse a?¿Qué función hace eloperator<< ¿Referirse a?

La deducción de argumento de plantilla (1) debe suceder antes de la resolución de sobrecarga (2), pero parece que (al menos una parte de) (2) se debe realizar para que (1) tenga éxito.

Las preguntas duplicadas algo relacionadas pero no relacionadas son:

¿Std :: endl funciona con cout y wcout?¿Por qué compila endl (std :: cout)¿Cómo funciona std :: flush?

Ninguna de esas preguntas ni ninguna de ellas responden al funcionamiento de la deducción de argumentos de plantilla que debe preceder a la resolución de sobrecarga, pero debe ser ayudada por esta última.

Siguiente pregunta: ¿Cómo funciona la resolución de sobrecarga cuando un argumento es una función sobrecargada?

Respuestas a la pregunta(4)

Su respuesta a la pregunta