2014-12-16 10 views
12

Ho linee semplici di codice, dove sto usando l'operatore di inserimento << per mostrare la stringa Hello World. Se uso un operatore b allora dovrebbe risultare a a.operator(b); Provo a fare la stessa cosa con l'operatore di inserimento e in uscita ho ricevuto l'indirizzo di stringa, piuttosto che la stringa effettiva.Perché l'operatore di inserimento sta stampando l'indirizzo anziché la stringa?

std::cout<<"Hello world"<<std::endl; 
std::cout.operator<<("Hello world").operator<<(std::endl); 

uscita:

Ciao mondo
0120CC74

Sto usando Visual Studio.

La conversione del mio operatore ha qualche problema?

+0

Riproducibile: http://coliru.stacked-crooked.com/a/eaf3b651349ebd39 –

risposta

18
std::cout<<"Hello world"<<std::endl; 

uso operatore di output overload per const char*, che è funzione libera, non funzione membro.

std::cout.operator<<("Hello world").operator<<(std::endl); 

uso operatore di output overload per const void*, dal momento che const char* è implicitamente convertibile in const void*.

si può guardare member overloads here e free overloads here

+0

risposta molto bella, grazie ..... – Libathos

5

La mia scommessa è che operatore funzione membro per std::ostream(char*) non sia sovraccarico.

Se si guarda alla ostream::operator<<, void* è risultato migliore e char* naturalmente viene convertito ad esso, mentre globale operator<<(std::basic_ostream), ha sovraccarichi esatte per char* tipi, che viene raccolto.

Ovviamente, si comportano in modo diverso.

+0

Ho appena notato che sono riuscito a deviare verso il basso questa risposta perfettamente valida. Il voto è sfortunatamente bloccato ormai, quindi non posso annullarlo, ma volevo chiarire che non c'è nulla di sbagliato in questa risposta. Scusate! :( –

+0

Ed ero solo 30 secondi in ritardo per essere il 1 °. Tanto ripetitore andato Oh, sono un povero ragazzo ... No biggies =).Penso di poterlo modificare, quindi puoi ritirare il tuo voto, non sono sicuro. Ma sto bene. – luk32

1

Come le altre risposte dicono, il problema è che si chiama esplicitamente la funzione membro operator <<, che non è sovraccaricata per const char*.

Per ottenere const char* sovraccarico, è necessario chiamare il operator << funzione libera, che viene opportunamente sovraccarico:

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

Allo stesso modo, non v'è alcuna funzione di sovraccarico senza operator << per aver scritto un std::ostream& (*)(std::ostream&), quindi per std::endl voi utilizzare la funzione membro.

Da questo, possiamo vedere che non è possibile riscrivere dalla sintassi dell'operatore di infisso (std::cout << ...) per funzionare con la sintassi di chiamata (operator << (...)) senza perdere la generalità.

+0

Mi piacerebbe convertire anche la chiamata a 'std :: endl' con questo stile, ma non riesco a gestirlo correttamente. Chiunque? –

+1

'endl' è in realtà una funzione template che considera lo stream come argomento. C'è un [sovraccarico della funzione membro] (http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt) per 'ostream' che utilizza il puntatore a funzione, che è il modo in cui funziona la tua versione esistente. –

+2

Quindi 'endl (operatore << (std :: cout," Hello World "));'. Nota che 'std ::' non è necessario a causa di ADL. –

Problemi correlati