2016-01-12 14 views
6

Esiste un modo in C++ per specificare qualsiasi tipo * come tipo di un modello, ad esempio tramite un carattere jolly o una parola chiave.Qualsiasi tipo generico in classe C++

Mi ricordo in Java che possiamo usare quello? carattere jolly come tipo generico, come HashMap<Long, ?>.

Provo a spiegare meglio la domanda utilizzando un codice di esempio. Supponiamo di avere la seguente classe Record:

template<typename T> 
class Record 
{ 
    private: 
     T content; 
     long size; 

    public: 
     Record(T _content, long _size) 
     { 
      this->content = _content; 
      this->size = _size; 
     } 

     T getContent() 
     { 
      return this->content; 
     } 

     long getSize() 
     { 
      return this->size; 
     } 
}; 

e supponiamo di voler utilizzare le istanze della classe sopra senza specificare il tipo esatto (io ho usato il nella seguente classe?), Semplicemente perché inutili nel caso in cui la classe di computer utilizza solo il metodo Record::getSize():

class Computer 
{ 
    public: 
     long long computeTotalSize(vector<Record<?>> recordVector) 
     { 
      long long totalSize = 0; 
      for (vector<Record<?>>::iterator it = recordVector.begin() ; it != recordVector.end(); ++it) 
       totalSize += (*it).getSize(); 

      return totalSize; 
     } 
}; 
+0

Se non si utilizza 'size()', perché non passare un vettore di dimensioni? Perché passare un vettore di 'Record'? Ad ogni modo puoi sempre usare qualche tipo di manichino minimale come 'char'. –

+3

Puoi far funzionare la funzione con qualsiasi tipo di record nello stesso modo in cui hai fatto Record funziona con qualsiasi tipo. – Kevin

+0

E come dice @Kevin, puoi semplicemente rendere 'computeTotalSize' un modello se vuoi gestire diversi tipi di' Record'. Un'alternativa è quella di derivare 'Record ' da un'interfaccia che dichiari una funzione virtuale 'size()'. Ma poi il vettore passato dovrebbe essere un vettore di puntatori (possibilmente intelligenti). –

risposta

8

è possibile effettuare computeTotalSize una funzione template con il parametro modello di record, come è parametro di modello:

template <typename T> 
long long computeTotalSize(vector<Record<T>> recordVector) 
{ 
    long long totalSize = 0; 
    for (vector<Record<T>>::iterator it = recordVector.begin() ; it != recordVector.end(); ++it) 
     totalSize += (*it).getSize(); 

     return totalSize; 
} 

nota che si dovrebbe anche passare il vettore con riferimento per evitare di copiare l'intera cosa:

long long computeTotalSize(const vector<Record<T>>& recordVector) 
+0

Sei stato più veloce, hai un +1 – Angew

7

Non può essere fatto allo stesso modo come in Java, perché i modelli C++ sono fondamentalmente diversi da generici Java (template C++ generano tipi completamente distinti, non costrutti di fantasia in cima a un tipo cancellato). Tuttavia, si potrebbe fare computeTotalSize un modello di funzione:

class Computer 
{ 
    public: 
     template <class T> 
     long long computeTotalSize(const vector<Record<T>>& recordVector) 
     { 
      long long totalSize = 0; 
      for (auto it = recordVector.begin() ; it != recordVector.end(); ++it) 
       totalSize += it->getSize(); 

      return totalSize; 
     } 
}; 

Avviso mi sono permesso di razionalizzare la sintassi del codice in qualche modo; l'unico cambiamento di comportamento sta usando const& per passare il vettore, per impedirne la copia.

noti che la modifica const& richiede getSize() da marcare in funzione const membro:

long getSize() const 
{ 
    return size; 
} 

Poiché sarebbe altamente inaspettato per una funzione chiamata getSize() per modificare l'oggetto su cui viene chiamata, questo è in realtà una buona cosa.