Vraag std :: vector als argument voor een sjabloonfunctie


Ik wil een klassemethode maken die een std :: vectorreferentie als argument gebruikt en ik wil deze gebruiken met verschillende soorten gegevens.

De functie moet er als volgt uitzien:

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

en ik wil het gebruiken met bijvoorbeeld:

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

Ik hoop dat ik mijn punt duidelijk heb gemaakt. Moet ik een dergelijke sjormethode maken:

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

of kan ik het op een andere manier doen? Als het moet, vertel me dan alsjeblieft hoe ik die methode in een klas kan schrijven.

Bedankt voor de hulp!


15
2017-09-30 12:30


oorsprong


antwoorden:


De juiste manier voor een template functie om te accepteren std::vector door const& is:

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

het tweede argument is de "allocator", en in een geavanceerd gebruik van std::vector het zal niet de standaard zijn. Als je het gewoon accepteert std::vector<T>, jouw some_func zal afwijzen std::vectors met alternatieve toewijzers.

Nu zijn er andere manieren om dit te benaderen, dat ik snel zal opsommen. Ik zal ze opsommen in dalende kosten: uitkeringsratio - die hierboven is waarschijnlijk wat je wilt, en de volgende is soms handig, en daarna vertak ik me in over ontwikkelde gevallen die zelden de moeite waard zijn om te overwegen (maar misschien handig zijn) in sommige gevallen in de hoek).

Je zou een willekeurig type kunnen accepteren T door T&& test dan om te bepalen of typename std::remove_reference<T>::type is een soort van std::vector. Dit zou u in staat stellen om "perfect doorgestuurd" te worden van de binnenkomende std::vector. Je kunt ook het predicaat wijzigen dat je gebruikt om te testen om meer te accepteren dan alleen een std::vector: voor het grootste gedeelte, const& naar std::vector heeft waarschijnlijk gewoon een willekeurige willekeurige toegangscontainer nodig.

Een belachelijk mooie manier zou zijn om een ​​tweestaps-functie uit te voeren. De tweede stap neemt een type-gewiste willekeurige bereikweergave (of alleen een bereikweergave als u geen willekeurige toegang nodig hebt) voor een vast type T met SFINAE om ervoor te zorgen dat het binnenkomende object compatibel is, leidt de eerste stap het containertype van het ingevoerde type af en roept de tweede stap in een SFINAE-context (auto some_func(...)->decltype(...)).

Als type-uitwissing van std::vector<T> const& naar een willekeurig bereikbereik van aaneengesloten Ts verliest niet veel functionaliteit, een voordeel zou zijn dat je zou kunnen garanderen dat het lichaam van je functie precies hetzelfde is std::vector<T> const& en voor T[n] en voor std::array<T,n>.

Het is geen groot voordeel, vooral niet voor de vereiste verwarmingsplaat.

 kan dit veel gemakkelijker maken, omdat de meerstappende SFINAE hierboven uiteen zal vallen in een paar clausules.


25
2017-09-30 13:05