2011-10-21 15 views
6

Ho il seguente codice C++:Cast in costruttori per C++ di tipo

#include <iostream> 
#include <string> 

    int main(int argc, char* argv[]) 
    { 
     const std::string s1 = "ddd"; 
     std::string s2(std::string(s1)); 
     std::cout << s2 << std::endl; 
    } 

Il risultato è: Perché? Quando uso -Wall bandiera, avviso del compilatore di scrittura: l'indirizzo del 'std :: string s2 (std :: string)' sarà sempre valutare come 'vero'

Ma questo codice:

#include <iostream> 
#include <string> 

int main(int argc, char* argv[]) 
{ 
    const std::string s1 = "ddd"; 
    std::string s2((std::string)(s1)); 
    std::cout << s2 << std::endl; 
} 

il risultato: ddd

E 'risultato normale

+3

Impossibile basta fare la seconda linea 's2 std :: string (S1);' Perché è necessario includi il secondo 'std :: string'? – rhololkeolke

+1

Perché creare una copia intermedia? Perché non 'std :: string s2 = s1;'? –

+0

@Oscar: la versione crea una variabile inizializzata predefinita intermedia e quindi copia tramite l'operatore di assegnazione copia. La versione corretta senza nulla di intermedio è rho's. – Xeo

risposta

13

Most-vexing-parse.

std::string s2(std::string(s1)); 

viene analizzato come la dichiarazione di una "funzione di prendere un parametro denominato std::strings1 e restituendo un std::string". Quindi prova a stampare quella funzione, che prima lo converte in un puntatore a funzione (normale decadimento/regola di conversione). Poiché lo di std::ostream non è sovraccarico per i puntatori di funzione in generale, tenterà una conversione in bool, che ha esito positivo e poiché il puntatore della funzione non è nulla, viene convertito nel valore booleano true, che viene stampato come 1.

Change a

std::string s2((std::string(s1))); 

o, meglio ancora, basta

std::string s2(s1); 
+0

Oppure 'std :: string s2 = s1;' –

+1

@Oscar: Copia ctor> operatore di assegnazione copia. :) – Xeo

+7

'std :: string s2 = s1;' chiama il costruttore di copie perché è una dichiarazione. –