Como “std :: cout << std :: endl;” é compilado?

A maioriaManipuladores de fluxo IO são funções regulares com a seguinte assinatura:

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

No entanto, alguns manipuladores (incluindo os mais usados -std::endl estd::flush) são modelos do seguinte formato:

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

Então, como é que a compilação destd::cout << std::endl; com êxito, pois o exemplo a seguir falha:

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

É claro que o contexto (emstd::cout << std::endl;) ajuda o compilador a desambiguar a referência astd::endl. Mas quais são as regras que governam esse procedimento? Parece um desafio real para sobrecarregar a resolução, que precisa responder a duas perguntas ao mesmo tempo:

Qual especialização destd::endl<CharT, Traits>() fazstd::endl referir-se?Qual função faz ooperator<< referir-se?

A dedução do argumento do modelo (1) deve ocorrer antes da resolução da sobrecarga (2), mas parece que (pelo menos uma parte de) (2) precisa ser executada para que (1) seja bem-sucedido.

As perguntas duplicadas, de certa forma relacionadas, mas de modo algum são:

Std :: endl funciona com cout e wcout?Por que o endl (std :: cout) compilaComo o std :: flush funciona?

Nenhuma dessas perguntas e nem as respostas para elas abordam o funcionamento da dedução de argumento de modelo que deve preceder a resolução de sobrecarga, mas deve ser ajudada por esta.

Questão a seguir: Como a resolução de sobrecarga funciona quando um argumento é uma função sobrecarregada?

questionAnswers(4)

yourAnswerToTheQuestion