2012-11-09 12 views
6
template<typename T> 
void print_size(const T& x) 
{ 
    std::cout << sizeof(x) << '\n'; 
} 

int main() 
{ 
    print_size("If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."); 
    // prints 115 
} 

Questa stampa 115 su un recente compilatore g ++. Quindi apparentemente, T viene dedotto per essere una matrice (invece di un puntatore). Questo comportamento è garantito dallo standard? Sono rimasto un po 'sorpreso, perché il codice seguente mostra le dimensioni di un puntatore e ho pensato che lo auto si comportasse esattamente come la deduzione degli argomenti del modello?Detrazione argomento template per stringhe letterali

int main() 
{ 
    auto x = "If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."; 
    print_size(x); 
    // prints 4 
} 
+1

Non ora per il primo ma il secondo non è inaspettato. I letterali delle stringhe sono array, no? – Tomek

+2

Per chi legge questo che non sa: non puoi passare array per valore (decadono ai puntatori) ma puoi sicuramente passare un riferimento a un array. Qui, 'const T &' diventa un riferimento a un array e quindi' sizeof' fornisce la dimensione dell'array. –

+1

La risposta di Martinho copre la domanda principale. Perché il comportamento è garantito, 14.8.2.1/2: "Se' P' non è un tipo di riferimento: Se 'A' è un tipo di matrice, il tipo di puntatore prodotto dalla conversione standard da matrice a puntatore viene utilizzato al posto di 'A' per tipo deduzione; ..." dove 'P' è il tipo di parametro di funzione di una funzione modello che può coinvolgere uno o più parametri di modello e' A' è il tipo di espressione utilizzato nella chiamata di funzione. – aschepler

risposta

8

auto si comporta esattamente come deduzione modello di argomentazione. Esattamente come T!

confrontare questo:

template<typename T> 
void print_size(T x) 
{ 
    std::cout << sizeof(x) << '\n'; 
} 

int main() 
{ 
    print_size("If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."); 
    // prints 4 
    auto x = "If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."; 
    print_size(x); 
    // prints 4 
} 

Con questo:

template<typename T> 
void print_size(const T& x) 
{ 
    std::cout << sizeof(x) << '\n'; 
} 

int main() 
{ 
    print_size("If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."); 
    // prints 115 
    const auto& x = "If you timidly approach C++ as just a better C or as an object-oriented language, you are going to miss the point."; 
    print_size(x); 
    // prints 115 
} 

Non abbastanza, ma questo non è uno dei casi d'angolo.

+0

Stupido me. Grazie per aver sollevato la tenda :) – fredoverflow

+0

Perché, ovviamente, non è possibile passare una matrice in stile C come valore in C++. – Yakk

+0

@ Yakk: Infatti, poiché ciò interromperà la compatibilità con C. C non aveva riferimenti, quindi non c'era alcun comportamento esistente da violare. – MSalters

Problemi correlati