template - typename c++




Memorizzazione delle definizioni di funzioni modello C++ in un file.CPP (8)

Ho un codice di modello che preferirei avere memorizzato in un file CPP anziché inline nell'intestazione. So che questo può essere fatto purché tu sappia quali tipi di template saranno usati. Per esempio:

.h file

class foo
{
public:
    template <typename T>
    void do(const T& t);
};

file .cpp

template <typename T>
void foo::do(const T& t)
{
    // Do something with t
}

template void foo::do<int>(const int&);
template void foo::do<std::string>(const std::string&);

Nota le ultime due righe: la funzione modello foo :: do viene utilizzata solo con ints e std :: stringhe, quindi tali definizioni significano che l'app si collegherà.

La mia domanda è - è un brutto scherzo o funzionerà con altri compilatori / linker? Sto solo usando questo codice con VS2008 al momento, ma vorrò portarlo in altri ambienti.


C'è, nell'ultimo standard, una parola chiave ( export ) che potrebbe aiutare ad alleviare questo problema, ma non è implementata in nessun compilatore di cui sono a conoscenza, oltre a Comeau.

Vedi le FAQ-lite su questo.


Il problema che descrivi può essere risolto definendo il modello nell'intestazione o tramite l'approccio che descrivi sopra.

Raccomando di leggere i seguenti punti dalle FAQ del C ++ Lite :

Entrano in molti dettagli su questi (e altri) problemi di modello.


Non c'è niente di sbagliato nell'esempio che hai dato. Ma devo dire che credo non sia efficiente memorizzare le definizioni delle funzioni in un file cpp. Capisco solo la necessità di separare la dichiarazione e la definizione della funzione.

Se utilizzato insieme all'istanza di classe esplicita, la libreria di controllo del concetto Boost (BCCL) può aiutare a generare il codice di funzione del modello nei file cpp.


Per gli altri su questa pagina chiedendo quale sia la sintassi corretta (come ho fatto io) per la specializzazione esplicita del template (o almeno in VS2008), è la seguente ...

Nel tuo file .h ...

template<typename T>
class foo
{
public:
    void bar(const T &t);
};

E nel tuo file .cpp

template <class T>
void foo<T>::bar(const T &t)
{ }

// Explicit template instantiation
template class foo<int>;

Questo codice è ben formato. Devi solo prestare attenzione che la definizione del modello è visibile nel punto di istanziazione. Per citare lo standard, § 14.7.2.4:

La definizione di un modello di funzione non esportato, un modello di funzione membro non esportato o una funzione membro non esportata o membro dati statici di un modello di classe deve essere presente in ogni unità di traduzione in cui viene esplicitamente istanziata.


Questo dovrebbe funzionare bene ovunque siano supportati i template. L'istanziazione esplicita del template è parte dello standard C ++.


Sì, questo è il modo standard per eseguire un'istanza esplicativa speciale . Come hai affermato, non puoi creare un'istanza di questo modello con altri tipi.

Modifica: corretta in base al commento.


Tempo per un aggiornamento! Crea un file inline (.inl, o probabilmente qualsiasi altro) e copia semplicemente tutte le tue definizioni in esso. Assicurati di aggiungere il template sopra ogni funzione ( template <typename T, ...> ). Ora invece di includere il file di intestazione nel file inline fai il contrario. Includere il file inline dopo la dichiarazione della classe ( #include "file.inl" ).

Non so davvero perché nessuno ha menzionato questo. Non vedo alcun inconveniente immediato.





templates