2014-12-03 12 views
5

Chciałbym mieć coś podobnego do std :: vector C++, gdzie podstawowe obiekty są niezmienne. Mogę więc dodać elementy typu push_back(), aby dodać je do wektora, itd. Rzeczywiste std :: vector utrzymuje tablicę poniżej tego, która jest większa niż rozmiar wektora, wypełniona domyślnymi obiektami skonstruowanymi, a kiedy push_back(), robi to przypisanie do elementu w tablicy. Moje niezmienne obiekty nie mają domyślnego konstruktora, a przypisanie jest operacją mutowania, więc to też się kończy.Zmienny kontener z niezmiennymi obiektami w C++

Potrafię wykonać vector<boost::optional<T>>, ale jest to niechlujny interfejs, ponieważ chcę tylko wstawiać prawidłowo skonstruowane obiekty do wektora i usuwać je tylko z wektora.

Myślałem, że doładowanie ma coś takiego, ale nie mogłem go znaleźć. Czy coś takiego istnieje?

+2

Przynajmniej w C++ 11 wektory działają tak, jak chcesz. Możesz użyć 'emplace_back()'. –

+0

Czy potrafisz przechowywać inteligentne wskaźniki do rzeczywistych niezmiennych obiektów w twoim wektorze? – shuttle87

+1

Sposób, w jaki opisujesz 'wektor ' nie pasuje dokładnie jak działa. Czy twój typ ma konstruktory przesuwania i/lub kopiowania? – hvd

Odpowiedz

4

Twoja koncepcja działania vector jest nieprawidłowa.

Wektor używa alokatora do przydzielenia pamięci pierwotnej. Ta surowa pamięć nie zawiera domyślnie skonstruowanych obiektów - jest to po prostu surowa pamięć.

Gdy wykonasz numer push_back (na przykład), wówczas zostanie użyte miejsce docelowe new do skonstruowania obiektu w pamięci pierwotnej. Podobnie, gdy będziesz obiekt, zakończy się on bezpośrednio wywoływaniem jego destruktora w celu przekształcenia obiektu z powrotem w surową pamięć.

Przy bieżącej (C++ 11 lub nowszej) implementacji std::vector obiekt nie musi obsługiwać domyślnej konstrukcji ani przypisania. Wspieranie konstrukcji ruchu i przeniesienie zadania powinny być wystarczające. Aby je użyć, należy użyć wartości emplace_back zamiast push_back.

+0

'push_back()' na wartości r także używa konstrukcji ruchu. – Angew

+1

@Angew: True. Podobnie, 'emplace_back' może zrobić kopię, jeśli masz typ, który nie obsługuje przenoszenia - ale wolałbym, aby kod odzwierciedlał rzeczywiste intencje, więc jeśli planujesz typ typu" tylko ruch ", wolałbym zobacz 'emplace_back', nawet jeśli' push_back' faktycznie działał. –

+0

OK, podoba mi się "kod, co masz na myśli", to ma sens. – Angew