std::optional<int&> xx;
po prostu nie kompiluje się do najnowszej migawki gcc-7.0.0. Czy standard C++ 17 zawiera odniesienia do std::optional
? A dlaczego tak nie jest? (Realizacja ze wskaźnikami w dedykowanym specjalizacji whould powodować żadnych problemów chyba.)Dlaczego GCC odrzuca std :: opcjonalnie dla referencji?
Odpowiedz
Ponieważ optional
, w standardzie C++ 17, nie zezwala na typy referencyjne. Zostało to wyłączone z projektu.
Istnieją dwa powody tego. Po pierwsze, strukturalnie rzecz biorąc, optional<T&>
jest odpowiednikiem T*
. Mogą mieć różne interfejsy, ale robią to samo.
Po drugie, komitet normalizacyjny nie uzyskał konsensusu co do tego, jak powinien zachowywać się numer optional<T&>
.
Rozważmy następujący:
optional<T&> ot = ...;
T t = ...;
ot = t;
Co należy zrobić, że ostatni wiersz? Czy pobieranie obiektu odwołuje się przez ot
i przypisanie do niego kopii, tak, że jest to *ot == t
? A może powinien ponownie powiązać zapisane odniesienie, takie, że ot.get() == &t
? Gorzej, czy będzie to do different things based on whether ot
was engaged or not przed zleceniem?
Niektórzy ludzie oczekują, że zrobi to jedno, a niektórzy ludzie będą oczekiwać, że zrobi to samo. Bez względu na to, którą stronę wybierzesz, ktoś będzie zdezorientowany.
Jeśli użył T*
zamiast byłoby całkiem jasne, które się dzieje:
T* pt = ...;
T t = ...;
pt = t; //Compile error. Be more specific.
*pt = t; //Assign to pointed-to object.
pt = &t; //Change pointer.
Cóż, nie zaakceptowałbym pierwszego powodu, ponieważ potrzebuję jednolitego interfejsu w ogólnym kodzie. Jeśli chodzi o drugi powód, dla mnie zdecydowanie powinien zachowywać się jak "* ot = t". A tak przy okazji, czy jest tak w przypadku 'boost :: optional'? – Vahagn
"Więc bez względu na to, którą stronę wybierzesz, ktoś będzie zdezorientowany." - A więc rozwiązaniem jest dezorientacja obu stron?.) – Vahagn
Jeśli 'ot' nie jest włączone, nawet rzuciłbym wyjątek podczas' ot = t'. – Vahagn
IN [opcjonalne]:
Program, który wymaga konkretyzacji szablonu opcjonalny dla typu referencyjnego lub do możliwie cv -kwalifikowane typy
in_place_t
lubnullopt_t
jest źle sformułowane.
Brak numeru std::optional<T&>
. Na razie będziesz musiał użyć std::optional<std::reference_wrapper<T>>
.
będzie to wsparcie '->'? 'Std :: reference_wrapper' nie wydaje się implementować' operator-> '. Więc 'o-> foo' nie zadziała. –
@ JohannesSchaub-litb Potrzebujesz dwóch pośredników - jak 'o-> get(). Foo', bo' -> 'po prostu podaje' reference_wrapper'. Mam nadzieję, że ostatecznie dostaniemy "opcjonalne
@Someprogrammerdude To nie działa jak 'optional'. W przeciwnym razie nie można mieć opcji "opcjonalnie". Możesz napisać opcjonalny typ, który obsługuje typy odniesienia. Boost's. Standard po prostu nie wybiera (ze względu na 'operator ='). –
Barry
Prawie cały punkt odniesienia jest, że nie są opcjonalne. – jthill
Co powiedzieliśmy na 'std :: optional>' :-D –