[C++] Utilizzo Template
Dopo aver letto del materiale online, ho capito a cosa servono i template, ma sto incontrando delle difficoltà ad utilizzarli in una classe.
Per semplificare le cose ho creato una semplice classe. Se definisco le funzioni nell'header non ci sono problemi, ma se voglio definirle esternamente non compila.
Dove sbaglio?
Per semplificare le cose ho creato una semplice classe. Se definisco le funzioni nell'header non ci sono problemi, ma se voglio definirle esternamente non compila.
Dove sbaglio?
#include <iostream> #include "ll.h" using namespace std; int main() { tizio <int> a(3); cout << a.get_valore() << endl; }
#ifndef LL_H_INCLUDED #define LL_H_INCLUDED template <typename T> class tizio { private: T valore; public: tizio(const T&); T get_valore(); }; #endif // LL_H_INCLUDED
#include "ll.h" template<typename T> tizio<T>::tizio(const T& _valore) { valore = _valore; } template<typename T> T tizio<T>::get_valore() { return valore; }
Risposte
La tua domanda sembra indicare che non hai capito a cosa servono i template!
Questo è un quesito classico sui template, se cerchi online trovi sicuramente una spiegazione dettagliata. La risposta breve è che la definizione del template dev'essere nella stessa unità di compilazione [credo sia questo il termine corretto] di quella in cui la classe template viene istanziata. Ciò significa che se la definizione di un metodo di una classe template non viene incluso nel file in cui istanzi il template, il compilatore non può sapere cosa istanziare per quello specifico set di parametri template.
Questo è un quesito classico sui template, se cerchi online trovi sicuramente una spiegazione dettagliata. La risposta breve è che la definizione del template dev'essere nella stessa unità di compilazione [credo sia questo il termine corretto] di quella in cui la classe template viene istanziata. Ciò significa che se la definizione di un metodo di una classe template non viene incluso nel file in cui istanzi il template, il compilatore non può sapere cosa istanziare per quello specifico set di parametri template.
In effetti ho letto qualcosa al riguardo oggi stesso, quindi non pretendo di aver esaurito l'argomento, ma più che non capire a cosa servono i template, credo che il problema sia stato quello di non sapere bene come lavora il compilatore in queste circostanze e di non essermi soffermato molto al riguardo...poi magari mi sbaglio.
Il materiale da cui ho studiato l'argomento indicava il modo da me utilizzato per definire "esternamente" la funzione-membro. Evidentemente con esternamente intendeva comunque nello stesso file.
In ogni caso grazie per la dritta.
Farò qualche ricerca al riguardo per approfondire la questione. In particolare mi chiedo se ci sia qualche escamotage per definire le funzioni-membro in un altro file.
Il materiale da cui ho studiato l'argomento indicava il modo da me utilizzato per definire "esternamente" la funzione-membro. Evidentemente con esternamente intendeva comunque nello stesso file.
In ogni caso grazie per la dritta.
Farò qualche ricerca al riguardo per approfondire la questione. In particolare mi chiedo se ci sia qualche escamotage per definire le funzioni-membro in un altro file.
Per utilizzare i template in maniera "esterna" devi, in aggiunta a quanto hai fatto, istanziare esplicitamente tutte le combinazioni che vuoi usare nel file
ll.cpp. Quelle che istanzi lì saranno poi disponibili al compilatore per l'utilizzo nel file
main.cpp.
Capisco, effettivamente è molto più conveniente mettere tutto nel file .h
Inoltre se qualcuno utilizzasse la classe template con tipi non nativi sarebbe costretto a modificare il file ll.cpp
Inoltre se qualcuno utilizzasse la classe template con tipi non nativi sarebbe costretto a modificare il file ll.cpp
Vedo che hai afferrato. In alcuni casi è ovvio quali siano i template che possono essere istanziati, ad esempio se il parametro è un intero e la classe ha senso solo per un ristretto numero di interi.
Si tratta di fatto di un problema legato al concetto stesso di file header del C++. Altri linguaggi con funzionalità simili non hanno infatti questo problema. Quando una classe template viene usata il compilatore genera il codice corrispondente alla particolare specializzazione usata. Per poterlo fare il compilatore ha bisogno di vedere l'implementazione del template che deve quindi essere inclusa all'interno della unità di compilazione. Il metodo più semplice è quello di inserire tutto in un singolo file header. Non vedo sinceramente ragioni per cercare di complicarsi la vita cercando di trovare soluzioni alternative*.
* Anche quando si conoscono tutti i tipi per cui specializzare la classe o funzione template. Anche perché a sto punto non vedo il vantaggio di usare una classe o funzione template..
* Anche quando si conoscono tutti i tipi per cui specializzare la classe o funzione template. Anche perché a sto punto non vedo il vantaggio di usare una classe o funzione template..