2013-09-30 18 views
12

Chcę utworzyć metodę klasy, która przyjmuje referencję std :: vector jako argument. Chcę go używać z różnymi typami danych.std :: wektor jako argument funkcji szablonu

więc chcę, aby funkcja jak:

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

i chcę z niego korzystać na przykład:

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

Mam nadzieję, że zrobiłem mój punkt przewagi. Czy muszę dokonać metody szablonu tak:

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

czy mogę to zrobić w inny sposób? Jeśli muszę, powiedz mi, jak mogę napisać tę metodę w klasie

Dzięki za pomoc!

+0

Tak, to jest sposób na zrobienie tego. A może pytasz o coś innego? – jrok

+2

Co ci dolega? – Asaf

+0

Odpowiedź na to pytanie jest samowystarczalna. Wystarczy dodać, że jeśli ktoś chce iterować takie wektory, użyj: 'for (nazwa_trybutu wektor :: const_iterator it = vect.begin(); it! = Vect.end(); ++ it)' –

Odpowiedz

22

Prawo sposobem dla template funkcja przyjąć dowolny std::vector przez const& jest:

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

drugi argument jest „podzielnik”, a w niektórych zaawansowanych wykorzystania std::vector nie będzie domyślna. Jeśli po prostu zaakceptujesz std::vector<T>, Twój some_func odrzuci std::vector s z alternatywnymi alokatorami.

Są inne sposoby podejścia, które szybko wymienię. Wymienię je w malejącym koszcie: stosunek korzyści - powyższy jest prawdopodobnie tym, czego oczekujesz, a następny jest czasem przydatny, a potem przejdę do zbyt skomplikowanych przypadków, które rzadko są warte rozważenia (ale mogą być przydatne w niektórych przypadkach narożnych).

Można zaakceptować dowolny typ T przez T&&, a następnie przetestować, aby ustalić, czy typename std::remove_reference<T>::type jest rodzajem std::vector. To pozwoliłoby ci na "perfekcyjne przesłanie" przychodzącego std::vector. Pozwoli to również zmienić predykat używany do testowania, aby zaakceptować więcej niż tylko std::vector: w większości przypadków, po prostu potrzebuje jakiegoś arbitralnego kontenera dostępu losowego.

Bezsensownie fantazyjny sposób polega na wykonaniu dwustopniowej funkcji. Drugi krok polega na usunięciu typu widoku losowego zakresu dostępu (lub tylko widoku zakresu, jeśli nie potrzebujesz dostępu losowego) dla stałego typu T z SFINAE, aby upewnić się, że przychodzący obiekt jest kompatybilny, pierwszy krok zakłada typ kontenera przekazanego typu i wywołuje drugi krok w kontekście SFINAE (auto some_func(...)->decltype(...)).

Jako typ usunięciem std::vector<T> const& do widzenia zakresu dostępie swobodnym z T S nie stracić dużo funkcjonalności, zaletą jest to, że można zagwarantować, że ciało swojej funkcji jest dokładnie taka sama dla std::vector<T> const& i T[n] i dla std::array<T,n>.

Nie jest to duża zaleta, szczególnie w przypadku wymaganego standardowego urządzenia.

C++ 1y może to znacznie ułatwić, ponieważ wieloetapowa SFINAE powyżej zapadnie się w kilka klauzul wymaga.

Powiązane problemy