Czy C++11 pozwala na wektor?
Wymagania kontenera uległy zmianie Z C++03 na C++11. Podczas gdy C++03 miał ogólne wymagania (np. kopiowalność i przypisywalność dla wektora), C++11 definiuje drobnoziarniste wymagania dotyczące każdej operacji kontenera (sekcja 23.2).
W rezultacie można np. zapisać typ, który jest kopiowalny, ale nie można go przypisać - np. struktura z elementem const - w wektorze, o ile wykonuje się tylko pewne operacje, które nie wymagają przypisania (Budowa i push_back
są takie operacje; insert
nie jest).
Zastanawiam się, czy to oznacza, że standard pozwala teraz vector<const T>
? Nie widzę powodu, dla którego nie powinna - const T
, podobnie jak struktura z członem const, jest typem, który można skopiować, ale nie można go przypisać - ale mogłem coś przeoczyć.
(część tego, co sprawia, że myślę, że mogłem coś przeoczyć, jest to, że bagażnik gcc ulega awarii i pali się, jeśli spróbujesz utworzyć instancję vector<const T>
, ale jest w porządku z vector<T>
Gdzie t ma członka const).
4 answers
Nie, wierzę, że wymagania alokatora mówią, że T może być "non-const, non-reference object type".
Nie byłabyś w stanie wiele zrobić z wektorem stałych obiektów. A const vector<T>
i tak byłoby prawie takie samo.
wiele lat później ta szybka i brudna odpowiedź nadal wydaje się przyciągać komentarze i głosy. Nie zawsze w górę. :-)
aby dodać odpowiednie referencje:
Dla standardu C++03, który mam na papierze, tabela 31 w sekcji [lib.allocator.wymagania] says:
T, U any type
Nie to jakikolwiek typ faktycznie zadziałał.
Następny standard, C++11, mówi w bliskim szkicu w [allocator.wymagania] i teraz tabela 27:
T, U, C any non-const, non-reference object type
Co jest niezwykle bliskie temu, co pierwotnie napisałem powyżej z pamięci. O to też chodziło w pytaniu.
Jednak w C++14 (draft N4296 ) Tabela 27 teraz says:
T, U, C any non-const object type
Być może dlatego, że Referencja może nie jest typem obiektu?
A teraz w C++17 (draft N4659 ) jest tabela 30, która mówi:
T, U, C any cv-unqualified object type (6.9)
Więc nie tylko const
jest wykluczone, ale także volatile
. Pewnie i tak stare wiadomości i tylko Wyjaśnienie.
proszę również zobaczyć Howard Hinnant informacje z pierwszej ręki , obecnie tuż poniżej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-02 20:51:43
Update
Pod zaakceptowaną (i poprawną) odpowiedzią skomentowałem w 2011 roku:
Podsumowując: nie zaprojektowaliśmy kontenerów do przechowywania
const T
. Chociaż tak przemyśl to. I byliśmy naprawdę blisko zrobienia tego przez wypadek. Z tego co wiem, obecny punkt jest para przeciążonychaddress
funkcji Członkowskich w domyślnej alokator: gdyT
jestconst
, te dwa przeciążenia mają takie same podpis. Łatwy sposób na poprawienie tego byłoby specjalizować sięstd::allocator<const T>
i usunąć jedno z przeciążeń.
W nadchodzącym projekcie C++17 wydaje mi się, że zalegalizowaliśmy vector<const T>
, i wierzę również, że zrobiliśmy to przypadkowo. :-)
P0174R0 usuwa przeciążenia address
z std::allocator<T>
. P0174R0 nie wspomina o poparciu std::allocator<const T>
w ramach swojego uzasadnienia.
Korekta
W komentarzach poniżej T. C. poprawnie zauważa, że address
przeciążenia są przestarzałe , nie są usuwane. Mój błąd. Członkowie nie pojawiają się w 20.10.9, gdzie std::allocator
jest zdefiniowany, ale zamiast tego są relegowani do sekcji D. 9. Zaniedbałem skanować Rozdział D dla tej możliwości, kiedy to opublikowałem.
Dziękuję T. C. za korektę. Rozważałem usunięcie tej mylącej odpowiedzi, ale być może najlepiej zostawić to z tą poprawką, aby być może powstrzyma to kogoś innego od błędnego odczytania specyfikacji w taki sam sposób jak ja tak.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-27 21:21:22
Mimo że mamy już bardzo dobre odpowiedzi na ten temat, postanowiłem przedstawić bardziej praktyczną odpowiedź, aby pokazać, co można, a czego nie można zrobić.
Więc to nie działa:
vector<const T> vec;
Po prostu przeczytaj inne odpowiedzi, aby zrozumieć dlaczego. I, jak pewnie się domyślacie, to też nie zadziała:
vector<const shared_ptr<T>> vec;
T
nie jest już const
, ale vector
trzyma shared_ptr
s, nie T
s.
Z drugiej strony to Działa :
vector<const T *> vec;
vector<T const *> vec; // the same as above
Ale w tym przypadku, const to obiekt, na który jest wskazywany, a nie sam wskaźnik (który przechowuje wektor). Byłoby to równoważne:
vector<shared_ptr<const T>> vec;
Co jest w porządku.
Ale jeśli umieścimy const
na końcu wyrażenia, to teraz zamieni wskaźnik w const
, więc nie będzie kompilacji:
vector<T * const> vec;
Trochę zagmatwane, zgadzam się, ale można się do tego przyzwyczaić.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-08 00:29:40
Uzupełniając Pozostałe odpowiedzi, należy zastosować inne podejście:
vector<unique_ptr<const T>> vec;
Jeśli jest to przypadek, w którym chcesz wyegzekwować, że tylko vec
ma własność swoich przedmiotów. Lub jeśli chcesz dynamicznie przenosić elementy do vec
i w pewnym momencie je przenieść.
Jak wspomniano, semantyka pointer const
może być myląca, ale shared_ptr
i unique_ptr
nie są. const unique_ptr<T>
jest wskaźnikiem const, a unique_ptr<const T>
jest wskaźnikiem const, jak można się spodziewać.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-05 12:14:44