2016-01-12 10 views
6

Gibt es in C++ die Möglichkeit, einen beliebigen Typ * als Typ einer Vorlage anzugeben, z. B. durch einen Platzhalter oder ein Schlüsselwort.Jeder generische Typ in C++ - Klasse

Ich erinnere mich in Java können wir das mit dem tun? Wildcard als generischer Typ, wie HashMap<Long, ?>.

Ich versuche, die Frage mit einem Beispielcode besser zu erklären. Angenommen, wir haben die folgende Record-Klasse:

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; 
     } 
}; 

und nehmen wir an Instanzen der oben genannten Klasse verwenden möchten, ohne den genauen Typ Angabe (I verwendet die in der folgenden Klasse?), Nur weil nutzlos in dem Fall, in dem die Klasse-Computer verwendet nur die Methode 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

Wenn nichts außer 'size()' verwendet wird, warum nicht einen Vektor von Größen übergeben? Warum einen Vektor von 'Record' übergeben? Wie auch immer, Sie können immer einen minimalen Dummy-Typ wie "char" verwenden. –

+3

Sie können die Funktion mit jedem Datensatztyp genauso arbeiten lassen, wie Sie Record mit einem beliebigen Typ erstellt haben. – Kevin

+0

Und wie @Kevin sagt, können Sie 'computeTotalSize' einfach zu einer Vorlage machen, wenn Sie mit verschiedenen' Record'-Typen arbeiten wollen. Eine Alternative ist das Ableiten von "Record " von einer Schnittstelle, die eine virtuelle 'size()' Funktion deklariert. Aber dann müsste der übergebene Vektor ein Vektor von (möglicherweise intelligenten) Zeigern sein. –

Antwort

8

Sie können eine Template-Funktion mit dem Datensatz Template-Parameter machen computeTotalSize als es Template-Parameter ist:

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; 
} 

Beachten Sie, dass Sie auch den Vektor durch Verweis übergeben sollte zu vermeiden, dass die ganze Sache zu kopieren:

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

Du warst schneller, hast +1 – Angew

7

Es ist nicht die gleiche Art und Weise wie in Java getan werden kann, weil C++ Vorlagen von Java Generics grundverschieden sind (C++ Vorlagen erzeugen völlig verschiedene Typen, keine ausgefallenen Konstrukte, oben ein vom Typ gelöschter Typ. Sie können jedoch computeTotalSize eine Funktionsschablone machen:

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; 
     } 
}; 

Mitteilung ich mir die Freiheit nahm, die Syntax des Codes etwas rationalisiert; Die einzige Verhaltensänderung besteht darin, den Vektor mit const& zu übergeben, um ein Kopieren zu verhindern.

Beachten Sie, dass der Wechsel zu const&getSize() erfordert als const Member-Funktion markiert werden:

long getSize() const 
{ 
    return size; 
} 

Da es sehr unerwartet für eine Funktion getSize() genannt wäre, das Objekt zu ändern, auf dem es heißt, dies ist eigentlich eine gute Sache.

Verwandte Themen