Tout d'abord, le compilateur va regarder les types à gauche et à droite de l' <<
. std::cout
est de type std::ostream
, le littéral de chaîne est de type tableau de 15 const char
. Que la gauche est de type classe, il sera à la recherche d'une fonction nommée operator<<
. La question est, où il va les chercher?
La recherche de ce nom operator<<
est un soi-disant non qualifiés de recherche, parce que le nom de la fonction n'est pas qualifié comme std::operator<<
. Non qualifiés de recherche pour les noms de fonction invoque l'argument dépendant de recherche. L'argument dépendant de recherche de recherche dans les classes et espaces de noms associés avec les types d'argument.
Lorsque vous incluez <iostream>
, une fonction libre de la signature
template<typename traits>
std::basic_ostream<char, traits>& operator<<(std::basic_ostream<char, traits>&,
const char*);
a été déclarée dans l'espace de noms std
. Cet espace de noms est associée avec le type d' std::cout
, donc cette fonction sera trouvé.
std::ostream
est juste un typedef pour std::basic_ostream<char, std::char_traits<char>>
, et le tableau de 15 const char
peut être converti implicitement à une char const*
(pointant vers le premier élément du tableau). Par conséquent, cette fonction peut être appelée avec les deux types d'arguments.
Il y a d'autres surcharges de operator<<
, mais la fonction que j'ai mentionné ci-dessus est le meilleur match pour les types d'argument et celui qui est sélectionné dans ce cas.
Un exemple simple de l'argument dépendant de recherche:
namespace my_namespace
{
struct X {};
void find_me(X) {}
}
int main()
{
my_namespace::X x;
find_me(x); // finds my_namespace::find_me because of the argument type
}
N. B. cette fonction est un opérateur, la recherche est un peu plus complexe. Il est recherché par qualifiée de recherche dans la portée de le premier argument (si c'est de type de classe), c'est à dire comme une fonction membre. En outre, non qualifié recherche est effectuée, mais en ignorant toutes les fonctions de membre. Le résultat est légèrement différent, car non qualifiés de recherche est en fait comme une procédure en deux étapes, où argument dépendant de recherche est la deuxième étape. Si la première étape trouve une fonction de membre de la deuxième étape n'est pas réalisée, c'est à dire de l'argument-dépendante de la recherche n'est pas utilisé.
Comparer:
namespace my_namespace
{
struct X
{
void find_me(X, int) {}
void search();
};
void find_me(X, double) {}
void X::search() {
find_me(*this, 2.5); // only finds X::find_me(int)
// pure unqualified lookup (1st step) finds the member function
// argument-dependent lookup is not performed
}
}
pour:
namespace my_namespace
{
struct X
{
void operator<<(int) {}
void search();
};
void operator<<(X, double) {}
void X::search() {
*this << 2.5; // find both because both steps are always performed
// and overload resolution selects the free function
}
}