Perché il template di essere implementato nel file di intestazione?

Citazione da La libreria standard del C++: un tutorial e manuale:

Il solo portatile modo di utilizzo dei modelli, al momento, è per la loro implementazione nel file di intestazione utilizzando le funzioni inline.

Perché è questo?

(Chiarimento: file di intestazione non sono il solo soluzione portatile. Ma sono la più conveniente soluzione portatile.)

La domanda non è corretto. C’è un altro portatile. Il modello di classe può essere esplicitamente creata un’istanza – come è stato sottolineato da altre risposte.
Se è vero che l’immissione di tutti i template di funzione definizioni nel file di intestazione è probabilmente il modo più conveniente per usarli, non è ancora chiaro che cosa è “in linea” nella citazione. Non c’è bisogno di utilizzare le funzioni inline. “In linea” non ha assolutamente nulla a che fare con questo.
Il libro è aggiornato.

OriginaleL’autore MainID | 2009-01-30

14 Replies
  1. 1266

    È non necessario mettere l’implementazione nel file di intestazione, vedere la soluzione alternativa alla fine di questa risposta.

    Comunque, il motivo per cui il codice è in difetto è che, quando si crea un’istanza di un modello, il compilatore crea una nuova classe di con il dato di modello di argomento. Per esempio:

    template<typename T>
    struct Foo
    {
        T bar;
        void doSomething(T param) {/* do stuff using T */}
    };
    
    //somewhere in a .cpp
    Foo<int> f; 

    Durante la lettura di questa linea, il compilatore crea una nuova classe (chiamiamolo FooInt), che è equivalente al seguente:

    struct FooInt
    {
        int bar;
        void doSomething(int param) {/* do stuff using int */}
    }

    Di conseguenza, il compilatore deve avere accesso alla implementazione dei metodi, per creare un’istanza con il modello argomento (in questo caso int). Se queste implementazioni non erano in intestazione, non sarebbe accessibile, e quindi il compilatore non sarebbe in grado di creare un’istanza del modello.

    Una soluzione comune a questo è quello di scrivere il modello di dichiarazione in un file di intestazione, quindi implementare la classe in un file di implementazione (ad esempio .tpp), e includere questo file di implementazione al fine di intestazione.

    //Foo.h
    template <typename T>
    struct Foo
    {
        void doSomething(T param);
    };
    
    #include "Foo.tpp"
    
    //Foo.tpp
    template <typename T>
    void Foo<T>::doSomething(T param)
    {
        //implementation
    }

    In questo modo, l’implementazione è ancora separato dalla dichiarazione, ma è accessibile per il compilatore.

    Un’altra soluzione è quella di mantenere l’attuazione separati, esplicitamente, di creare un’istanza di tutte le istanze del modello di cui avete bisogno:

    //Foo.h
    
    //no implementation
    template <typename T> struct Foo { ... };
    
    //----------------------------------------    
    //Foo.cpp
    
    //implementation of Foo's methods
    
    //explicit instantiations
    template class Foo<int>;
    template class Foo<float>;
    //You will only be able to use Foo with int or float

    Se la mia spiegazione non è abbastanza chiaro, si può avere uno sguardo al C++ Super-FAQ su questo argomento.

    In realtà l’esplicita istanza deve essere in .file cpp che ha accesso alle definizioni per tutti Pippo funzioni membro, piuttosto che nell’intestazione.
    “il compilatore deve avere accesso alla implementazione dei metodi, per creare un’istanza con il modello argomento (in questo caso di tipo int). Se queste implementazioni non erano in intestazione, non sarebbe accessibile”, Ma perché è un’implementazione nel .cpp file non è accessibile per il compilatore? Un compilatore è in grado, inoltre, di accesso .cpp informazioni, altrimenti come si sarebbe svolta in .i file obj? EDIT: risposta a questa domanda è nel link fornito in questa risposta…
    Non credo che questo spiega la questione che, chiaramente, la cosa fondamentale è ovviamente correlato con l’UNITÀ di compilazione, che non è menzionato in questo post
    le strutture e le classi sono equivalenti, con l’eccezione che il default modificatore di accesso per le classi è “privato”, mentre è pubblico per le strutture. Ci sono alcune piccole differenze che si può imparare guardando domanda.
    L’uso esplicito di creazione di un’istanza in caso contrario si otterrà molto lento costruisce presto..

    OriginaleL’autore Luc Touraille

  2. 209

    Un sacco di correggere le risposte qui, ma ho voluto aggiungere questo (per completezza):

    Se si, in fondo l’attuazione cpp file, fare esplicita la creazione di istanze di tutti i tipi di modello verrà utilizzato con il linker sarà in grado di trovare loro come al solito.

    Modifica: Aggiunta di esempio di una esplicita istanza modello. Utilizzato dopo che il modello è stato definito, e tutte le funzioni membro è stato definito.

    template class vector<int>;

    Questo verrà creata un’istanza (e quindi rendere disponibile per il linker) la classe e tutte le sue funzioni di membro di (solo). Sintassi simile lavori per il modello funzioni, in modo che se non si ha un membro operatore sovraccarichi potrebbe essere necessario fare la stessa cosa per quelli.

    L’esempio di cui sopra è abbastanza inutile in quanto vettore è completamente definito nelle intestazioni, ad eccezione di quando un comune file di intestazione precompilata?) utilizza extern template class vector<int> in modo da tenerlo da istanziare in tutti i altri (1000?) i file in vettoriale.

    Ugh. Buona risposta, ma nessuna vera soluzione pulita. Listato di tutti i tipi possibili per un modello non sembra che un modello deve essere.
    Questo può essere un bene, in molti casi, ma in genere si rompe lo scopo del modello, che è pensato per consentire di utilizzare la classe con qualsiasi type senza indicare manualmente.
    vector non è un buon esempio a causa di un container è di per sé targeting “tutti i tipi”. Ma succede molto spesso che si crea modelli che sono solo significava per una serie specifica di tipi, per esempio i tipi numerici: int8_t, int16_t, int32_t, uint8_t, uint16_t, etc. In questo caso, ha ancora senso utilizzare un modello, ma in modo esplicito un’istanza di loro per l’intero insieme di tipi è anche possibile e, a mio parere, raccomandato.
    Utilizzato dopo che il modello è stato definito, “e tutte le funzioni membro che è stato definito”. Grazie !
    Vorrei sapere, è possibile fare esplicita istanze da qualche parte che il classe’ intestazione o del file di origine? Per esempio, fare in main.cpp?

    OriginaleL’autore MaHuJa

  3. 185

    È a causa del requisito per la compilazione separata e poiché i modelli sono la creazione di istanze di stile polimorfismo.

    Permette di avvicinarci un po ‘ di cemento per una spiegazione. Dico sempre che ho i seguenti file:

    • pippo.h
      • dichiara l’interfaccia di class MyClass<T>
    • foo.cpp
      • definisce l’attuazione di class MyClass<T>
    • bar.cpp
      • utilizza MyClass<int>

    Compilazione separata significa che dovrebbe essere in grado di compilare foo.cpp indipendentemente dal bar.cpp. Il compilatore fa tutto il duro lavoro di analisi, ottimizzazione e la generazione di codice su ogni unità di compilazione, in modo completamente indipendente; non abbiamo bisogno di fare tutto il programma di analisi. E ‘ solo il linker che deve gestire l’intero programma in una sola volta, e il linker del lavoro è sostanzialmente più facile.

    bar.cpp non ha nemmeno bisogno di esistere quando compila foo.cpp, ma dovrei ancora essere in grado di collegare il pippo.o ho già avuto insieme con il bar.o ho appena prodotto, senza bisogno di ricompilare foo.cpp. foo.cpp potrebbe anche essere compilato in una libreria dinamica, distribuito da qualche altra parte senza foo.cpp, e legata con il codice che scrivono anni dopo ho scritto foo.cpp.

    “La creazione di istanze di stile polimorfismo” significa che il modello MyClass<T> non è davvero una classe generica che può essere compilato in codice che può funzionare per qualsiasi valore di T. Che vorresti aggiungere overhead come la boxe, la necessità di passare puntatori a funzione per i contatori e i costruttori, etc. L’intenzione dei template C++ è per evitare di dover scrivere quasi identici class MyClass_int, class MyClass_float, ecc, ma ancora essere in grado di finire con la compilazione del codice, che è per lo più come se ci aveva scritto ogni versione separatamente. Così un modello è letteralmente un modello; un modello di classe è non una classe, è una ricetta per la creazione di una nuova classe per ogni T incontriamo. Un modello non può essere compilato in codice, solo il risultato di creare il modello può essere compilato.

    Così, quando foo.cpp della compilazione, il compilatore non può vedere bar.cpp sapere che MyClass<int> è necessario. Si può vedere il modello MyClass<T>, ma non può emettere il codice (si tratta di un modello, di una classe). E quando bar.cpp della compilazione, il compilatore è in grado di vedere che è necessario creare un MyClass<int>, ma non può vedere il modello MyClass<T> (solo la sua interfaccia in pippo.h) e quindi non può creare.

    Se foo.cpp utilizza MyClass<int>, quindi il codice per che verranno generati durante la compilazione di foo.cpp, in modo che quando bar.o è legata a pippo.o possono essere agganciati e di lavoro. Possiamo usare questo fatto per consentire a un insieme finito di modello istanze di essere realizzati .file cpp scrivendo un unico modello. Ma non c’è un modo per bar.cpp di utilizzare il modello di come modello e creare un’istanza di qualsiasi tipi di volontà; è possibile utilizzare solo i pre-versioni esistenti di classe basata su modelli che l’autore di foo.cpp pensato per fornire.

    Si potrebbe pensare che durante la compilazione di un modello, il compilatore deve “generare tutte le versioni”, con quelli che non vengono mai utilizzati filtrato durante il collegamento. A parte l’enorme sovraccarico di lavoro e l’estrema difficoltà di un simile approccio volto, perché “modificatore di tipo” caratteristiche come puntatori e array consentono anche solo il built-in tipi di dar luogo ad una infinità di tipi, che cosa succede quando rivolgo ora il mio programma con l’aggiunta di:

    • baz.cpp
      • dichiara e implementa class BazPrivate, e utilizza MyClass<BazPrivate>

    Non vi è alcun modo possibile che questo potrebbe funzionare a meno che non ci sia

    1. Ricompilare foo.cpp ogni volta che si cambia qualsiasi altro file nel programma, in caso di aggiunta di un nuovo romanzo di creazione di un’istanza di MyClass<T>
    2. Richiedono che baz.cpp contiene (eventualmente attraverso l’intestazione include) il modello completo di MyClass<T>, in modo che il compilatore è in grado di generare MyClass<BazPrivate> durante la compilazione di baz.cpp.

    Non piace a nessuno (1), perché tutto il programma di analisi di compilazione, i sistemi di per sempre per la compilazione , e perché rende impossibile distribuire compilate le librerie senza il codice sorgente. Quindi, siamo (2), invece.

    sottolineato citazione modello è, letteralmente, un modello, un modello di classe non è una classe, è una ricetta per la creazione di una nuova classe per ogni T incontriamo
    Vorrei sapere, è possibile fare esplicita istanze da qualche parte che il classe’ intestazione o del file di origine? Per esempio, fare in main.cpp?
    Si dovrebbe essere in grado di farlo da qualsiasi file che ha accesso all’intero modello di attuazione (sia perché è nello stesso file o in via di intestazione include).
    Come una risposta? Esso non offre alcuna soluzione, ma solo retorica.
    Non è retorica. La domanda è: “perché è necessario implementare modelli di intestazione?”, io ho spiegato le scelte tecniche del linguaggio C++ fa che portare a questo requisito. Prima ho scritto la mia risposta altri già fornito soluzioni che non sono pieno di soluzioni, perché c’è non essere una soluzione completa. Ho sentito queste risposte dovrebbero essere integrate da un dibattito più ampio del “perché” l’angolo della questione.

    OriginaleL’autore Ben

  4. 67

    Modelli devono essere istanziato dal compilatore, prima di compilare in codice oggetto. La presente istanza può essere raggiunto solo se il modello di argomenti conosciuti. Ora immaginate uno scenario in cui un modello di funzione viene dichiarata in a.h, definito in a.cpp e utilizzato in b.cpp. Quando a.cpp è compilato, non è necessariamente noto che la prossima compilation b.cpp richiederà un’istanza del modello, figuriamoci l’istanza specifica che sarebbe. Per ulteriori intestazione e file di origine, la situazione può rapidamente ottenere più complicato.

    Si può sostenere che i compilatori possono essere resi più intelligenti di “guardare in avanti” per tutti gli usi del modello, ma sono sicuro che non sarebbe difficile creare ricorsiva o altrimenti complicati scenari. Per quanto ne so, i compilatori di non fare tale aspetto anticipata. Anton rilevato, alcuni compilatori supportano esplicite dichiarazioni di esportazione del modello di istanze, ma non tutti i compilatori supportano (ancora?).

    “export” è standard, ma è solo difficile da attuare e quindi la maggior parte del compilatore squadre solo ancora non hai fatto.
    esportazione non elimina la necessità per fonte informativa, né ridurre la compilazione dipendenze, mentre richiede un enorme sforzo da compilatore costruttori. Così Herb Sutter stesso chiese compilatore costruttori di ‘dimenticare’ di esportazione. Come l’investimento di tempo necessario sarebbe meglio spendere altrove…
    Quindi non credo che l’esportazione non è implementata con ‘sicurezza’. Probabilmente mai ottenere fatto da chiunque altro che EDG dopo che gli altri visto quanto tempo è passato, e quanto poco è stato ottenuto
    Se ti interessa, la carta è detta “Perché non possiamo permetterci di esportazione”, ha elencato sul suo blog (gotw.ca/pubblicazioni), ma non pdf (un rapido google dovrebbe girare, però)
    Ok, grazie per il buon esempio e spiegazione. Ecco la mia domanda però è: perché il compilatore non è in grado di capire dove il modello si chiama, e compilare i file prima di compilare il file di definizione? Posso immaginare che può essere fatto in un caso semplice… È la risposta che interdipendenze incasinerà ordine molto veloce?

    OriginaleL’autore David Hanak

  5. 50

    In realtà, prima di C++11 standard definiti i export parola chiave che sarebbe rendere possibile dichiarare modelli in un file di intestazione e la loro attuazione altrove.

    Nessuno dei popolari compilatori implementato questa parola chiave. L’unico che conosco è il frontend scritto da Edison Gruppo di Progettazione, che viene utilizzato dal Comeau compilatore C++. Tutti gli altri, è necessario scrivere template nel file di intestazione, perché il compilatore deve la definizione di un modello per la corretta creazione di un’istanza (come altri hanno sottolineato già).

    Come risultato, la ISO C++ standard comitato ha deciso di rimuovere il export funzione di modelli con C++11.

    In conseguenza di esportazione del modello è stato rimosso dal C++11.
    Non ho capito, grazie. In pratica, si poteva utilizzare export, comunque, dato che potrebbe legare con lo Comeau compilatore. Era un “morto funzione”; solo mi sarebbe piaciuto vedere attuate ubiquitously.
    …e un paio di anni più tardi, I finalmente capito cosa export avrebbe in realtà dato noi, e cosa no… e ora io sono pienamente d’accordo con la EDG persone: non ci hanno portato quello che la maggior parte delle persone (me in ’11 incluso) credo, e il C++ standard è meglio senza di essa.
    questa carta è politico, ripetitivo e mal scritti. che non è il solito standard a livello di prosa. Uneedingly lungo e noioso, dicendo fondamentalmente 3 volte le stesse cose attraverso decine di pagine. Ma io sono informati ora che l’esportazione non è l’esportazione. Che è una buona intel !
    Buon sviluppatore e buon scrittore tecnico sono due distinti insiemi di capacità. Alcuni possono fare entrambe le cose, molti non possono. 😉

    OriginaleL’autore DevSolar

  6. 32

    Anche se in C++ standard non ha tale requisito, in quanto alcuni di essi richiedono che tutte le funzioni e modelli di classe devono essere disponibili in ogni unità di traduzione sono utilizzati. In effetti, per coloro i compilatori, i corpi delle funzioni del modello devono essere rese disponibili in un file di intestazione. A ripetere: questo significa che i compilatori non permettono loro di essere definito in non-header file, ad esempio .i file cpp

    C’è un esportazione parola chiave che dovrebbe attenuare questo problema, ma non è neanche lontanamente vicino ad essere portatile.

    Perché non riesco a implementare .file cpp con la parola chiave “in linea”?
    È possibile, e non è necessario mettere “in linea” anche. Ma devi essere in grado di utilizzarli solo in che file cpp e in nessun altro luogo.
    Questo è quasi più preciso risposta, tranne che “questo significa che i compilatori non permettono loro di essere definito in non-header file, ad esempio .i file cpp” è palesemente falsa.

    OriginaleL’autore Anton Gogolev

  7. 26

    Modelli devono essere utilizzati nelle intestazioni perché il compilatore ha bisogno di creare un’istanza di diverse versioni del codice, secondo i parametri indicati/dedotta per i parametri del modello. Ricordate che un modello non rappresenta direttamente il codice, ma un modello per diverse versioni del codice.
    Quando si compila un non-modello di una funzione in un .cpp file, la compilazione di una concreta funzione/classe. Questo non è il caso per i modelli, che possono essere istanziati con diversi tipi, vale a dire, cemento codice deve essere emessa in caso di sostituzione parametri del modello con calcestruzzi.

    C’era una funzione con il export parola chiave che è stato pensato per essere utilizzato per la compilazione separata.
    Il export funzionalità è obsoleta in C++11 e, per quanto ne so, solo un compilatore messa in atto. Non si deve fare uso di export. Compilazione separata non è possibile, in C++ o C++11, ma forse in C++17, se i concetti che fanno, si potrebbe avere qualche modo di compilazione separata.

    Per la compilazione separata da raggiungere, separato modello di organismo di controllo deve essere possibile. Sembra che una soluzione è possibile con i concetti. Date un’occhiata a questo carta recentemente presentato al
    standard commitee incontro. Penso che questo non è l’unico requisito, in quanto è ancora necessario creare un’istanza di codice per il codice del modello e nel codice utente.

    La compilazione separata problema per i modelli credo sia anche un problema che si manifesta con la migrazione a moduli, che è attualmente in fase di elaborazione.

    OriginaleL’autore Germán Diago

  8. 13

    Significa che la maggior parte dei portatili modo per definire le implementazioni del metodo di classi template è quello di definire all’interno della definizione di classe del modello.

    template < typename ... >
    class MyClass
    {
    
        int myMethod()
        {
           //Not just declaration. Add method implementation here
        }
    };

    OriginaleL’autore Benoît

  9. 9

    Anche se ci sono un sacco di spiegazioni sopra, mi manca in un modo pratico per modelli separati in intestazione e corpo.

    La mia preoccupazione principale è evitare la ricompilazione di tutti gli utenti del modello, quando posso modificare la sua definizione.

    Avendo tutti i template istanze del modello di corpo non è una soluzione praticabile per me, dal momento che il modello di autore non può sapere se il suo utilizzo e il modello utente non può avere il diritto di modificarlo.

    Ho preso il seguente metodo, che funziona anche per i vecchi compilatori gcc (4.3.4, aCC A. 03.13).

    Per ogni modello di utilizzo c’è un typedef nel proprio file di intestazione (generata da un modello UML). Il suo corpo contiene l’istanza (che finisce in una libreria che è collegato alla fine).

    Ogni utente del modello contiene il file di intestazione e utilizza il typedef.

    Un esempio schematico:

    MyTemplate.h:

    #ifndef MyTemplate_h
    #define MyTemplate_h 1
    
    template <class T>
    class MyTemplate
    {
    public:
      MyTemplate(const T& rt);
      void dump();
      T t;
    };
    
    #endif

    MyTemplate.cpp:

    #include "MyTemplate.h"
    #include <iostream>
    
    template <class T>
    MyTemplate<T>::MyTemplate(const T& rt)
    : t(rt)
    {
    }
    
    template <class T>
    void MyTemplate<T>::dump()
    {
      cerr << t << endl;
    }

    MyInstantiatedTemplate.h:

    #ifndef MyInstantiatedTemplate_h
    #define MyInstantiatedTemplate_h 1
    #include "MyTemplate.h"
    
    typedef MyTemplate< int > MyInstantiatedTemplate;
    
    #endif

    MyInstantiatedTemplate.cpp:

    #include "MyTemplate.cpp"
    
    template class MyTemplate< int >;

    main.cpp:

    #include "MyInstantiatedTemplate.h"
    
    int main()
    {
      MyInstantiatedTemplate m(100);
      m.dump();
      return 0;
    }

    In questo modo solo il modello e le istanze devono essere ricompilate, non tutti gli utenti del modello (e dipendenze).

    OriginaleL’autore lafrecciablu

  10. 6

    Che è esattamente corretto, perché il compilatore deve sapere di che tipo è per l’allocazione. Così template di classi, funzioni, enumerazioni,ecc.. devono essere attuato anche nel file di intestazione, se deve essere fatto in pubblico o di una parte di una libreria (statico o dinamico), perché i file di intestazione NON viene compilato, a differenza del c/cpp file. Se il compilatore non sa che il tipo è di non compilarlo. In .Net può, perché tutti gli oggetti che derivano dalla classe Object. Questo non è .Net.

    “file di intestazione NON sono compilati” – è davvero strano modo di descrivere. File di intestazione può essere parte di una unità di traduzione, proprio come una “c/cpp” file.
    In realtà, è quasi l’opposto della verità, che è il file di intestazione sono molto spesso compilati molte volte, mentre un file di origine è di solito compilato una sola volta.

    OriginaleL’autore Robert

  11. 6

    Se il problema è l’extra tempo di compilazione e dimensioni dei binari di bloat prodotto dalla compilazione dell’ .h come parte di tutte le .cpp moduli di utilizzo, in molti casi, ciò che si può fare è rendere il modello di classe scendere da un non-templatized classe di base per non dipendente dal tipo di parti dell’interfaccia, e che la classe base può avere la sua attuazione nel .file cpp.

    Questa risposta dovrebbe essere modded molto di più. I “indipendente” scoperto il tuo stesso approccio e stato specificamente alla ricerca di qualcuno con cui l’ho utilizzata già, dato che sono curioso di sapere se è un schema ufficiale e se ha un nome. Il mio approccio è quello di implementare un class XBase ovunque ho bisogno di implementare un template class X, mettendo a seconda del tipo di parti in X e tutto il resto in XBase.

    OriginaleL’autore Eric Shaw

  12. 2

    Un modo per separare l’implementazione è come indicato di seguito.

    //inner_foo.h
    
    template <typename T>
    struct Foo
    {
        void doSomething(T param);
    };
    
    
    //foo.tpp
    #include "inner_foo.h"
    template <typename T>
    void Foo<T>::doSomething(T param)
    {
        //implementation
    }
    
    
    //foo.h
    #include <foo.tpp>
    
    //main.cpp
    #include <foo.h>

    inner_foo ha forward dichiarazioni. pippo.tpp è l’attuazione e comprende inner_foo.h; e pippo.h avrà una sola riga, per includere pippo.tpp.

    In fase di compilazione, il contenuto di pippo.h vengono copiati pippo.tpp e quindi l’intero file viene copiato pippo.h dopo di che si compila. In questo modo, non c’è nessuna limitazione, e la denominazione è coerente, in cambio di un file aggiuntivo.

    Faccio questo perché statico analizzatori per il codice di pausa, quando non vede avanti le dichiarazioni di classe *.tpp. Questo è fastidioso quando si scrive codice in qualsiasi IDE o utilizzando YouCompleteMe o di altri.

    OriginaleL’autore Pranay

  13. 1

    Il compilatore genera codice per ogni istanza modello quando si utilizza un modello durante la fase di compilazione.
    Per la compilazione e il processo di collegamento .cpp file vengono convertiti a puro oggetto o codice macchina che li contiene riferimenti o i simboli non definiti perché il .h i file che sono inclusi nel vostro main.cpp non hanno implementazione di SICUREZZA. Questi sono pronti per essere collegati con un altro oggetto file che definisce un’implementazione per il tuo modello, e quindi hai un full.fuori eseguibile.
    Tuttavia, poiché i modelli devono essere elaborati in fase di compilazione per generare il codice per ogni modello di istanza che si fanno nel vostro programma principale, il collegamento non guida perché la compilazione del main.cpp in main.o e quindi la compilazione del modello .cpp nel modello.o e quindi il collegamento non si può raggiungere il template scopo perché sto collegando diversi modello di istanza per lo stesso modello di attuazione! E i modelli sono dovuto fare il contrario mi.e per avere un’implementazione, ma consentono di molte istanze, attraverso l’utilizzo di una classe.

    Significato typename T ottenere sostituito durante la fase di compilazione non il collegamento di passaggio, in modo che se cerco di compilare un modello senza T di essere sostituito come un concreto valore tipo così non può funzionare, perché quella è la definizione di modelli di un tempo di compilazione di processo, e btw meta-programmazione è tutto su come usare questa definizione.

    OriginaleL’autore Moshe Rabaev

  14. 1

    Solo per aggiungere qualcosa di degno di nota qui. Si possono definire i metodi di una classe basata su modelli bene in attuazione di file quando non sono in funzione dei modelli.


    myQueue.hpp:

    template <class T> 
    class QueueA {
        int size;
        ...
    public:
        template <class T> T dequeue() {
           //implementation here
        }
    
        bool isEmpty();
    
        ...
    }    

    myQueue.cpp:

    //implementation of regular methods goes like this:
    template <class T> bool QueueA<T>::isEmpty() {
        return this->size == 0;
    }
    
    
    main()
    {
        QueueA<char> Q;
    
        ...
    }

    OriginaleL’autore Nik-Lz

Lascia un commento