2013-09-30 9 views
12

Ich möchte eine Klassenmethode, die Std :: Vektor-Referenz als Argument zu machen. Ich möchte es mit verschiedenen Arten von Daten verwenden.Std :: Vector als Vorlage Funktion Argument

so möchte ich Funktion machen, wie:

void some_function(const std::vector & vect){ //do something with vector } 

und ich es verwenden möchte mit zum Beispiel:

std::vector<int> v1; 
some_function(v1); 
std::vector<string> v2; 
some_function(v2); 

Ich hoffe, dass ich meinen Standpunkt klar gemacht. Muss ich zu Template-Methode so machen:

template<class T> 
void some_function(std::vector<T> & vect){} 

oder ich kann es auf andere Weise? Wenn ich muss, sag mir, wie ich diese Methode schreiben kann in Klasse

Vielen Dank für Ihre Hilfe!

+0

Ja, das ist der Weg, es zu tun. Oder fragst du etwas anderes? – jrok

+2

Was ist los mit dir vorgeschlagen? – Asaf

+0

Die Antwort auf diese Frage ist autark. Um hinzuzufügen, dass, wenn jemand solche Vektoren iterieren möchte, verwenden Sie dann: 'for (type vector :: const_iterator = vect.begin(); it! = Vect.end(); ++ it)' –

Antwort

22

Der richtige Weg für eine template Funktion jeder std::vector von const& zu akzeptieren ist:

template<typename T, typename A> 
void some_func(std::vector<T,A> const& vec) { 
} 

das zweite Argument ist die „Allocator“, und in einigen fortgeschrittenen Verwendung von std::vector wird es nicht der Standard sein. Wenn Sie nur std::vector<T> akzeptieren, wird Ihr std::vector s mit alternativen Zuordnern zurückweisen.

Nun, es gibt andere Möglichkeiten, dies zu nähern, die ich schnell auflisten werde. Ich werde sie in abnehmendem Kosten-Nutzen-Verhältnis auflisten - das obige ist wahrscheinlich das, was Sie wollen, und das nächste ist manchmal nützlich, und danach werde ich mich in überentwickelte Fälle verzweigen, die selten in Betracht gezogen werden (aber vielleicht nützlich sind) in einigen Eckfällen).

Sie könnten einen beliebigen Typ T von T&& dann Test, um zu bestimmen, ob typename std::remove_reference<T>::type ist eine Art std::vector akzeptieren. Dies ermöglicht Ihnen eine "perfekte Weiterleitung" der eingehenden std::vector. Es würde Ihnen auch erlauben, das Prädikat zu ändern, das Sie verwenden, um mehr als nur eine std::vector zu akzeptieren: in den meisten Fällen benötigt const& bis std::vector wahrscheinlich nur einige beliebige Random-Access-Container.

Ein lächerlich schicker Weg wäre, eine zweistufige Funktion zu tun. Im zweiten Schritt wird eine Typ-gelöschte Random-Access-Bereichsansicht (oder nur eine Bereichsansicht, wenn Sie keinen Direktzugriff benötigen) für einen festen Typ T mit SFINAE verwendet, um sicherzustellen, dass das eingehende Objekt kompatibel ist Containertyp des übergebenen Typs und ruft den zweiten Schritt in einem SFINAE-Kontext auf (auto some_func(...)->decltype(...)).

Als Typ Löschung von std::vector<T> const& auf einen Schreib-Lese-Bereich Blick auf T s verliert nicht viel Funktionalität, wäre ein Vorteil, dass Sie, dass der Körper Ihrer Funktion garantieren kann, ist genau das gleiche für std::vector<T> const& und für T[n] und für std::array<T,n>.

Es ist kein großer Vorteil, vor allem für den erforderlichen Standard.

C++ 1y kann dies viel einfacher machen, weil die obige mehrstufige SFINAE in einige requires-Klauseln zerfallen wird.

Verwandte Themen