@Gene: assign () chce zarezerwować () niezbędną ilość pamięci z wyprzedzeniem. Użyje iteratorów wejściowych, aby określić, ile jest potrzebne, chyba że iteratory są ściśle InputIterator, w którym to przypadku pominie rezerwowanie i spowoduje ponowne przydzielenie dla każdej push_back (). Na drugim końcu spektrum BiderectionalIterators pozwoliłoby mu po prostu odjąć koniec - początek. Iteratory std :: set nie są jednak żadnymi z nich (są ForwardIterator) i jest to niefortunne: w tym przypadku assign () po prostu przejdzie cały zestaw, aby określić jego rozmiar - zła wydajność na dużych zestawach.
std::copynie dodaje elementów do kontenera, do którego wstawiasz: nie może; ma tylko iterator do kontenera. Z tego powodu, jeśli przekazujesz iterator wyjściowy bezpośrednio do std::copy, musisz upewnić się, że wskazuje zakres, który jest co najmniej wystarczająco duży, aby pomieścić zakres wejściowy.
std::back_insertertworzy iterator danych wyjściowych, który wywołuje push_backkontener dla każdego elementu, więc każdy element jest wstawiany do kontenera. Alternatywnie możesz utworzyć wystarczającą liczbę elementów w elemencie, std::vectoraby pomieścić kopiowany zakres:
Cześć James, zamiast twojej linii std :: copy (pierwszy blok kodu w twojej odpowiedzi), czy nie mogłem po prostu zrobić output.insert(output.end(), input.begin(), input.end());zamiast tego?
Twoja pierwsza inicjalizacja wektora jest nieprawidłowa. Tworzysz tablicę input,size()pustych wpisów, a następnie dołączasz kolejne. Myślę, że masz zamiar użyć std::vector<double> output; output.reserve(input.size()); std::copy(...);.
To nie zasługuje na -1. W szczególności pozwala to wektorowi na wykonanie tylko jednej alokacji (ponieważ nie może określić odległości ustawionych iteratorów w O (1)), a jeśli nie został zdefiniowany dla wektora, aby wyzerował każdy element podczas konstruowania, mogłoby to warto pozwolić, aby kopia sprowadziła się do mempa. To ostatnie mogłoby być nadal opłacalne, gdyby implementacja wykryła, że pętla w ktorach wektora może zostać usunięta. Oczywiście to pierwsze można też osiągnąć z rezerwą.
Dałem ci -1, ale z mojej strony było to cienkie. Dokonaj niewielkiej zmiany, abym mógł cofnąć mój głos, a dam ci +1: jest to właściwie bardzo czyste rozwiązanie ze względu na właściwość polegającą na tym, że pierwsza nie działa.
Dopiero co się zorientowałem, że jeśli samodzielnie edytuję odpowiedź, mogę zagłosować za. Zrobiłem to, dał ci +1 za alokację pamięci w pierwszej kolejności. Przepraszam!
W ten sposób będziemy wywoływać konstruktor kopiujący tylko dla każdego elementu, w przeciwieństwie do wywoływania najpierw konstruktora domyślnego, a następnie kopiowania operatora przypisania dla innych rozwiązań wymienionych powyżej. Więcej wyjaśnień poniżej.
Można użyć back_inserter, ale wywoła on push_back () na wektorze ( https://en.cppreference.com/w/cpp/iterator/back_insert_iterator ).
embrace_back () jest bardziej wydajna, ponieważ unika tworzenia tymczasowego przy użyciu push_back () . Nie jest to problem z trywialnie skonstruowanymi typami, ale będzie implikował wydajność dla nietrywialnie skonstruowanych typów (np. Std :: string).
Musimy unikać konstruowania wektora z argumentem size, który powoduje, że wszystkie elementy są domyślnie konstruowane (za nic). Jak na przykład z rozwiązaniem używającym std :: copy () .
I wreszcie, metoda vector :: assign () lub konstruktor pobierający zakres iteratora nie są dobrymi opcjami, ponieważ będą wywoływać std :: distance () (aby poznać liczbę elementów) na iteratorach set . Spowoduje to niepożądaną dodatkową iterację przez wszystkie elementy zestawu , ponieważ zestaw jest strukturą danych Binary Search Tree i nie implementuje iteratorów dostępu swobodnego.
Używamy plików cookie i innych technologii śledzenia w celu poprawy komfortu przeglądania naszej witryny, aby wyświetlać spersonalizowane treści i ukierunkowane reklamy, analizować ruch w naszej witrynie, i zrozumieć, skąd pochodzą nasi goście.
Kontynuując, wyrażasz zgodę na korzystanie z plików cookie i innych technologii śledzenia oraz potwierdzasz, że masz co najmniej 16 lat lub zgodę rodzica lub opiekuna.
assign()
funkcja:output.assign(input.begin(), input.end());