2016-11-02 64 views
5

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?

+1

@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

+1

Prawie cały punkt odniesienia jest, że nie są opcjonalne. – jthill

+1

Co powiedzieliśmy na 'std :: optional >' :-D –

Odpowiedz

5

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. 
+0

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

+0

"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

+0

Jeśli 'ot' nie jest włączone, nawet rzuciłbym wyjątek podczas' ot = t'. – Vahagn

2

IN [opcjonalne]:

Program, który wymaga konkretyzacji szablonu opcjonalny dla typu referencyjnego lub do możliwie cv -kwalifikowane typy in_place_t lub nullopt_t jest źle sformułowane.

Brak numeru std::optional<T&>. Na razie będziesz musiał użyć std::optional<std::reference_wrapper<T>>.

+0

będzie to wsparcie '->'? 'Std :: reference_wrapper' nie wydaje się implementować' operator-> '. Więc 'o-> foo' nie zadziała. –

+0

@ JohannesSchaub-litb Potrzebujesz dwóch pośredników - jak 'o-> get(). Foo', bo' -> 'po prostu podaje' reference_wrapper'. Mam nadzieję, że ostatecznie dostaniemy "opcjonalne ", które ponownie wiąże się z zadaniem, przekonałem się przez wielu ludzi, że to jest właściwe zachowanie. – Barry