2016-07-11 30 views
7

W documentation widzę, że std::vector<bool> jest zoptymalizowany pod kątem wydajności kosmicznej, dzięki czemu każda wartość boolowska zajmuje jeden bit. Z dokumentacji:std :: wektor <bool> implementacja optymalizacji

Sposób, w jaki std :: vector uzyskuje efektywność przestrzenną (a także to, czy jest w ogóle zoptymalizowany) jest zdefiniowaną implementacją.

Czy to oznacza, że ​​zależy to od implementacji kompilatora? Jeśli tak, to gdzie mogę sprawdzić, czy mój kompilator je obsługuje? Dlaczego nie mieliby go wspierać? Wydaje się, że jest to bardzo prosta i wydajna implementacja.

Jeśli nie, co to znaczy i co oznacza, że ​​chcę, aby ta optymalizacja miała miejsce?

Używam zestawu narzędzi TDM GCC.

+1

Tak, oznacza to, że implementacja 'std :: vector ' jest w dużej mierze zależna od kompilatora. Może nie być w ogóle zoptymalizowany lub może być zoptymalizowany w sposób specyficzny dla implementacji. Ogólnie rzecz biorąc, można to znaleźć, sprawdzając dokumentację kompilatora. Z GCC i innymi narzędziami open-source, przypuszczam, że możesz również sprawdzić kod źródłowy. Ale to nie tylko wymaga więcej pracy, ale może nie być dobrym pomysłem, ponieważ kod źródłowy dokumentuje tylko implementację, a nie kontrakt. –

+1

Łatwym sposobem sprawdzenia, czy taka optymalizacja jest zapewniona, jest sprawdzenie, czy 'std :: vector :: reference_type' to' bool & 'lub coś innego. W tym drugim przypadku masz typ proxy, który powinien być dozwolony tylko dla "zoptymalizowanej" implementacji. –

+1

@MatteoItalia 'std :: vector :: reference' jest wymagane, aby być proxy, nawet jeśli implementacja faktycznie nie pakuje bitów. –

Odpowiedz

2

Formalna definicja języka nie chce wykluczać sensownych implementacji, więc zawsze muszą być ostrożni.

Na przykład typowa kompilacja debugowania jest nadal zgodna ze standardami, ale można bardzo dobrze zauważyć, że nie jest kompresowany w trybie debugowania.

Teraz to nie jest nieokreślona ale implementacja zdefiniowana. Oznacza to, że fakt, czy jest skompresowany, powinien znajdować się gdzieś w dokumentacji kompilatora, ale Standard nie opisuje sposobu organizacji dokumentacji.

Jeśli twój kompilator nie obsługuje go tak, jak chcesz, możesz po prostu użyć innej biblioteki vector<bool> Zazwyczaj nie jest to klasa, która zależy od głębokiej magii kompilatora, więc alternatywy są łatwe do napisania.

0

Jest to zależne od wdrożenia i nie jest przenośne. Wygląda na to, że ma pewne wady konstrukcyjne i powinieneś unikać używania vector<bool>. Więcej szczegółów można uzyskać z "Efektywnego STL Meyersa, pozycja 18".

Jeśli naprawdę interesuje Cię oszczędność miejsca, możesz zamiast tego użyć std::bitset.

+0

Niestety nie mogę użyć 'std :: bitset', ponieważ potrzebuję dynamicznej inicjalizacji. – Simon

+3

FWIW, Boost ma [dynamic_bitset] (http://www.boost.org/doc/libs/1_61_0/libs/dynamic_bitset/dynamic_bitset.html), ale czasami Boost może być przesadą. Jeśli wiesz, jak z niego korzystać, 'std :: vector ' nie jest tak źle, po wszystkim, jak [niektóre uwaga] (https://isocpp.org/blog/2012/11/on-vectorbool). – legends2k

3

Implementacja zdefiniowana oznacza, że ​​zależy to od tego, co stanowi parametry abstrakcyjnej maszyny. (I.E., algorytmy definiujące twój system operacyjny hosta, specyfikację implementacji i wywołania systemowe). Informacyjny Q & A na co „realizacja zdefiniowana” Oznacza to here.

Więcej niż prawdopodobne, jeśli masz nowoczesną maszynę z nowoczesnym kompilatora/IDE, obsługuje definicję realizacji.

Jeśli kompilator nie robi” t obsługuje go, jest mało prawdopodobne, ponieważ nie "chce" go, ale ponieważ jest to bardzo stary kompilator lub maszyna o bardzo ograniczonej zasobności. wykona to na swój sposób (np. 32-bitowy vs 64-bitowy itp.) Nie wpływa to na przenośność, chyba że działa z (bardzo) starszą kompilacją er. Możesz sprawdzić specyfikacje wersji kompilatora, jeśli jest to problem, który można łatwo znaleźć w Internecie, szukając kompilatora i jego wersji.