Pourquoi l’appel explicite de l’opérateur << sur std :: cout provoque-t-il une sortie inattendue?

J’étais simplement curieux de savoir ce qui se passerait si std::cout explicitement l’ operator<< sur std::cout car j’avais appris que a.operator() était exactement identique à a() . Alors je le fais et ça imprime quelque chose de bizarre:

 #include  using std::cout; int main() { cout.operator<<("Hello World"); } 

Output: 0x80486a0

Bizarrement, il émet une adresse (l’adresse peut être différente pour vous mais elle doit quand même être une adresse). Je pense que c’est l’adresse de la chaîne, alors j’essaie de la déréférencer pour la faire sortir par la chaîne:

 *( cout.operator<<("Hello World") ); 

Mais je reçois une très longue erreur

no match for operator* in '*std::cout.std::basic_ostream<...

Je pense que c’est assez bizarre. Rien dans la définition de std::cout ne me ferait croire que cela provoquerait un comportement différent; également compte tenu du fait que l’appel explicite de la fonction d’opérateur ne fait aucune différence (ou devrait au moins).

Alors, pourquoi est-ce que je reçois cette sortie? Pourquoi est-ce que je reçois une adresse plutôt que la chaîne lorsque j’appelle explicitement l’opérateur? Est-ce même cette adresse en mémoire ou juste une sortie de mémoire? Toutes les réponses sont appréciées.

L’opérateur de sortie pour les chaînes intégrées, c’est-à-dire si on prend un caractère char const* comme argument, n’est pas membre de std::ostream . L’opérateur prenant un caractère char const* est une fonction non-membre qui serait appelée comme

 operator<< (std::cout, "Hello World"); 

Cependant, un membre prend un void const* qui formate la valeur du pointeur en utilisant la notation hexadécimale. Ce membre est la meilleure correspondance lorsque vous std::ostream explicitement un pointeur à un operator<< () membre operator<< () de std::ostream .

Le déréférencement des résultats d'un operator<<() ne fonctionne pas: les opérateurs retournent un std::ostream& qui n'a pas d' operator*() unaire operator*() surchargé. Si vous vouliez déréférencer l'argument, appelez-le ainsi:

 std:cout.operator<< (*"Hello World"); 

Cependant, cela ne ferait que distraire le caractère char const* auquel le littéral de chaîne se désintègre, donnant un caractère individuel H La fonction de sortie de caractère n'est pas non plus une fonction membre, alors que les opérateurs de sortie pour les entiers le sont, c'est-à-dire qu'elle afficherait la valeur de caractère de H Pour un système utilisant ASCII, il s'agirait de 72 .

Je pense que le problème ici est que l’ operator << qui imprime une chaîne de style C dans un stream de sortie est en fait une fonction libre , pas une fonction membre de basic_ostream . Cependant, basic_ostream a un operator<< , qui enregistre un void* et affiche son adresse. Par conséquent, si vous essayez explicitement d'appeler l' operator<< tant que fonction membre, vous appelez la version qui imprime une adresse de la chaîne de style C, plutôt que la fonction free qui imprime les caractères d'une chaîne.

Vous pouvez le voir en appelant

 operator<< (std::cout, "Hello, world!"); 

Ce qui effectivement imprime la chaîne.

J'espère que cela t'aides!