Proszę wyjaśnić, jaka jest różnica między union
a std::variant
i dlaczego std::variant
zostało wprowadzone do standardu? W jakich sytuacjach powinniśmy używać std::variant
na oldschool'owym union
?Gdzie użyć std :: variant over union?
Odpowiedz
Ogólnie rzecz biorąc, należy wolisz variant
chyba jeden z następujących podchodzi:
Oszukujesz. Robisz typowanie lub inne rzeczy, które są UB, ale masz nadzieję, że twój kompilator nie złamie twojego kodu.
Wykonujesz niektóre z pseudo-punkenów, które mogą być wykonywane przez C++
union
: konwersję między typami zgodnymi z układem lub między typowymi sekwencjami początkowymi.Użytkownik wyraźnie potrzebuje nieznacznej możliwości kopiowania i/lub zgodności układu.
variant<Ts>
nie muszą mieć określonego układu ani łatwej kopiowalności.unions
standardowych typów układów to układ standardowy, a trywialnie kopiowane typyunion
można kopiować trywialnie.Należy pamiętać, że istnieje a proposal to make
variant
trivially copyable if its component types are trivially copyable. Jest on proponowany jako raport dotyczący wady w stosunku do C++ 17, więc to zachowanie zostałoby skutecznie przeniesione do C++ 17.Potrzebujesz wsparcia niskiego poziomu do przełączania obiektów w miejscu. Używanie bufora pamięci dla takich rzeczy nie zapewnia trywialnych gwarancji kopiowania, które można uzyskać z
union
.
Podstawową różnicą między nimi jest, że variant
wie który wpisz je przechowuje, a union
spodziewa się śledzić, które z zewnątrz. Jeśli więc spróbujesz uzyskać dostęp do niewłaściwej pozycji w variant
, otrzymasz wyjątek lub nullptr
. Natomiast wykonanie z wartością union
jest jedynie niezdefiniowanym zachowaniem.
union
to narzędzie niższego poziomu, a zatem powinno być używane tylko wtedy, gdy bezwzględnie potrzebujesz niższego poziomu.
variant
posiada również maszyny do prowadzenia wizytacji, co oznacza, że można dostać się do uniknięcia konieczności pęczek if
sprawozdania gdzie zapytać „czy jest typu X, to zrobić. Jeśli jest typu Y, zrobić, itp.”
"tylko niezdefiniowane zachowanie" nie jest frazą, którą widzę bardzo często. :-) * Doskonała * odpowiedź, chociaż. "Motywacja" jest tu główną motywacją i wydaje się obejmować w dużej mierze 2 i 4. –
@CodyGray: # 2 i # 4 są całkowicie zgodne z prawem. Naprawdę nie oszukują tak bardzo, jak rzeczy, które wyglądają, jakby oszukiwały. –
- 1. Jak mogę użyć SUM() OVER()
- 2. Wysyłanie i odbieranie std :: string over socket
- 3. boost :: variant recursive trouble
- 4. Nie można zainicjować std :: variant z różnymi wyrażeniami lambda
- 5. boost :: variant konwersja do typu
- 6. Czy można użyć klauzuli SELECT INTO z UNION [ALL]?
- 7. Gdzie należy użyć Rx?
- 8. Kątomierz - gdzie użyć browser.waitForAngular()
- 9. C++ over wątku
- 10. Jak mogę użyć over według partycji w LINQ?
- 11. mysql zapytanie dwie tabele, UNION i gdzie klauzula
- 12. W jaki sposób można użyć std :: bind?
- 13. Czy możesz użyć `std :: remove_if` na kontenerze` std :: unique_ptr`?
- 14. Należy użyć std :: set lub std :: unordered_set dla zestawu wskaźników?
- 15. Jaki jest odpowiednik opcji boost :: variant w bibliotece standardowej C++?
- 16. std :: list i std :: for_each: gdzie jest mój koniec?
- 17. Egistential Quantification over Values
- 18. Należy użyć std :: move na zlecenie nullptr?
- 19. Do czego można użyć std :: remove_extent?
- 20. Czy możesz ponownie użyć przeniesionego std :: string?
- 21. Android Studio Instrumentation testing build variant
- 22. Dlaczego kompilator wybiera bool over string dla niejawnej typecast L ""?
- 23. MYSQL UNION DISTINCT
- 24. Jak przekonwertować między TVarRec i Variant?
- 25. Różnice między out_of_range, range_error i over/underflow_error?
- 26. Kiedy i gdzie należy użyć WCF
- 27. ROW_NUMBER() bez over w SQL
- 28. MIDI Over Bluetooth
- 29. Błąd Redis Over
- 30. Mojolicious over HTTPS
Myślę, że "union" nie zezwala na obiekty inne niż POD. I nawet jeśli tak to robi (tzn. Program nie ulega natychmiastowemu zawieszeniu), nie zapewnia wywołania właściwego destruktora. – yeputons
Wszędzie, gdzie chcesz wpisać bezpieczeństwo i pracujesz z nietrywialnymi typami. – user975989
Mam sprzeczność i nieporozumienie na temat std :: variant podczas oglądania tego filmu przez Jason Turner: https://www.youtube.com/watch? V = 3wm5QzdddYc –