2016-06-25 13 views
6

Ho sovraccaricato una funzione nella mia classe di stringhe, tuttavia, non viene mai chiamata. Perché?Funzione Templated non chiamata

template <class T> 
class StringT { 
public: 
    void assign(const T* ptr); 
    template <size_t N> void assign(const T(&ptr)[N]); 
}; 

int main() { 
    StringT<char> str; 
    str.assign("Hello World"); //calls "void assign(const T* ptr)" although type is (const char[12]) 
} 
+1

Interessante, non me lo sarei aspettato. Ho fatto un esempio leggermente più complesso qui: http://cpp.sh/7hnfk che concorda con l'asserzione di Microsoft che auto s = "cosa"; genererà un const char * (https://msdn.microsoft.com/en-us/library/69ze775t.aspx) per impostazione predefinita. – Arunas

risposta

6

Per ulteriori riferimento, alcuni riferimenti specifici al standard sono:

13.3.3 migliore funzione vitale

Data questa definizione, una funzione valida F1 è definita per essere una funzione migliore di un'altra funzione valida F2 se per tutti gli argomenti i, ICSi (F1) non è una sequenza di conversione peggiore di ICSi (F2), e quindi. ..

  • F1 non è una specializzazione di modello di funzione e F2 è una specializzazione di modello di funzione ...

In questo caso, la funzione non-templated è (ovviamente) non è un modello di funzione specializzazione e conversione da "Hello World" a char const* non è peggiore di a const char[N], in base alle regole di classificazione definite nella tabella nella sezione "Sequenze di conversione standard". In base a tale tabella, sia No conversions required sia Array-to-pointer conversion sono considerati una corrispondenza esatta nel contesto della risoluzione di sovraccarico. Allo stesso modo, se i sovraccarichi basati su modelli vengono modificati in un overload non di modello (ad esempio, come void assign(const T(&ptr)[12]);), la compilazione di str.assign("Hello World"); non riuscirà a causa di una chiamata ambigua.

Per assicurarsi che la funzione non-modello non viene presa in considerazione per il sovraccarico, c'è la seguente nota nella sezione "esplicita specificazione modello argomento":

Nota: Un elenco modello di argomenti vuota può essere utilizzato per indicare che un determinato uso fa riferimento a una specializzazione di un modello di funzione anche quando è visibile una funzione non di modello (8.3.5) che altrimenti verrebbe utilizzata.

Quindi, è possibile utilizzare str.assign<>("Hello World"); per quello.

+0

grazie per questo chiarimento. Potresti anche postare un link a quello standard? – mvidelgauz

+0

Le versioni standard non sono liberamente disponibili da quello che posso dire, ma puoi ottenere le bozze delle copie su http://www.open-std.org/jtc1/sc22/wg21/ nella [ultima bozza disponibile pubblicamente] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf) link. Non sono sicuro se c'è un modo migliore, però ... – mkal

+2

Sto ancora cercando di conciliare questo con il fatto che: StringT str; char hw_array [] = "Hello World"; str.assign (hw_array); chiama la versione modello – Arunas

3

Quando c'è una scelta, il compilatore sceglie la funzione più specializzata. Quando v'è una funzione non template di quello che viene considerato come più specializzati rispetto a qualsiasi funzione template

dettagli here

Se si desidera mantenere la funzione non-modello, ma con la forza chiamare modello di una prova

str.template assign("Hello World"); 
+0

può dipendere dal compilatore, ma se la versione const T * è commentata, l'altro viene chiamato al suo posto. Non vedo errori interessanti. – Arunas

+0

@Arunas Ho modificato la mia risposta, quindi i nostri commenti sono ora irrilevanti. Ho eliminato il mio – mvidelgauz

+0

C'è un modo per far sì che il compilatore chiami la funzione template? – Philinator

Problemi correlati