2013-06-07 11 views
11

Używam vector w programie C++ (a ja jestem początkującym).
Muszę wysłać część funkcji vector.Czy możemy wysłać część wektora jako argument funkcji?

Jeśli było c muszę to zrobić (z tablicami):

int arr[5] = {1, 2, 3, 4, 5}; 
func(arr+2); //to send part array {3, 4, 5} 

Czy istnieje inny sposób niż tworzenie nowego vector z ostatniej części?

+2

"Jeśli byłby c, muszę to zrobić (z tablicami): *" To by zakładało, że 'func' wiedział, że wymaga on tablicy złożonej z 3 elementów (lub mniej). Jeśli spodziewa się tablicy 5, jesteś spieprzony. –

+0

To całkiem możliwe, że powinieneś robić coś zupełnie innego. Dlaczego przekazujesz surowe dane? Co reprezentuje wektor? Osadziłem go i wykonałem na nim operacje, zamiast przekazywać je gdzie indziej. –

Odpowiedz

20

Popularnym podejściem jest przekazanie pasma iteracyjnej. To będzie działać ze wszystkimi rodzajami zakresach, w tym te należące do standardowych pojemników bibliotecznych i zwykłych tablic:

template <typename Iterator> 
void func(Iterator start, Iterator end) 
{ 
    for (Iterator it = start; it !=end; ++it) 
    { 
    // do something 
    } 
} 

następnie

std::vector<int> v = ...; 
func(v.begin()+2, v.end()); 

int arr[5] = {1, 2, 3, 4, 5}; 
func(arr+2, arr+5); 

Note: Chociaż funkcja działa dla wszystkich rodzajów zakresów, nie wszystkie typy iteratorów obsługują przyrost poprzez operator+ używany w v.begin()+2. Aby uzyskać alternatywy, spójrz na std::advance i std::next.

+3

Powiedziałbym to szerzej: funkcja działa dla wszystkich ** zakresów **. Kontenery i tablice to jeden ze sposobów zarządzania zakresami, ale nie są one jedynym sposobem. –

+0

@PeteBecker Dobry punkt. Edytowane. – juanchopanza

1
std::vector<char> b(100); 
send(z,&b[0],b.size(),0); 

Wypróbuj to.

Read this too.

+0

Masz na myśli '& b [2]', nieprawdaż? –

+0

Przeczytaj również moją zaktualizowaną odpowiedź. –

+0

Działa to doskonale dla wektorów, ponieważ są one przyległe. http: // stackoverflow.com/questions/849168/are-stdvector-elements-guaranteed-to-be-contiguous. Tylko uważaj, aby nie wypróbować tego typu rzeczy za pomocą nieciągłych pojemników do przechowywania. – kmort

6

Ogólnie można wysłać iteratory.

static const int n[] = {1,2,3,4,5}; 
vector <int> vec; 
copy (n, n + (sizeof (n)/sizeof (n[0])), back_inserter (vec)); 

vector <int>::iterator itStart = vec.begin(); 
++itStart; // points to `2` 
vector <int>::iterator itEnd = itStart; 
advance (itEnd,2); // points to 4 

func (itStart, itEnd); 

To będzie działać z więcej niż tylko vector s. Jednakże, ponieważ vector zagwarantował contigious magazynowania, tak długo, jak vector nie realokacji można wysyłać adresy elementów:

func (&vec[1], &vec[3]); 
0

Jak inni już wspomniano można użyć iteratorów za to. Będziesz musiał przekazać początek sekwencji i koniec sekwencji do swojej funkcji pracownika.

Jeśli potrzebujesz większej elastyczności, powinieneś spojrzeć na slice. Dzięki slice możesz na przykład pobrać co n-ty wpis wektora.

0

Byłem też przylgnęło do samego problem.I znaleźć naprawdę ładne trick.Suppose chcesz znaleźć minimum w zakresie L do R (włącznie) od arr następnie można zrobić coś takiego:

vector<int>arr = {4,5,1,3,7}; 

int minVal = *min_element(begin(arr)+L,begin(arr)+(R+1)); 

Oznacza, że ​​przekazujesz całą tablicę i zakres, a następnie możesz zastosować powyższą sztuczkę.

Powiązane problemy