Dlaczego std::runtime_error
nie dostarcza konstruktora akceptującego std::string&&
? Patrząc na the constructors for std::string
, ma konstruktor ruchu, ale specyfikacja noexcept
jest dostępna tylko dla C++ 14, a nie C++ 11. Czy to był błąd, nieosiągalny termin, czy coś mi brakuje?konstruktor ruchu dla std :: runtime_error
Odpowiedz
explicit runtime_error(string&&);
nie istnieje tylko dlatego, że nie zapewniają żadnej optymalizacji.
Okazuje się, że zgodny z C++ 11 runtime_error
nie przechowuje wewnątrz urządzenia std::string
. Powodem jest to, że członkowie kopii runtime_error
nie mogą zgłaszać wyjątków. W przeciwnym razie niewłaściwy wyjątek mógłby zostać zgłoszony, gdy kompilator skopiuje obiekt wyjątku podczas jego rzucania.
Oznacza to, że runtime_error
musi przechowywać niezmienny łańcuch referencyjny zliczany. Jednak C++ 11 zakazuje implementacji COW dla std::string
. Implementacje std::string
przeszły do "optymalizacji krótkich łańcuchów", która musi zostać przydzielona przy konstrukcji kopii, jeśli długość struny przekracza "krótki limit". I nie ma ograniczenia długości łańcuchów używanych do konstrukcji runtime_error
.
Tak skutecznie C++ 11 (i do przodu) zawiera dwie implementacje ciągi:
std::string
: Jest to zazwyczaj krótki ciąg zoptymalizowane typ z konstruktora kopii i skopiować zadanie, które jest w stanie rzucanie wyjątków.std::runtime_error
: Jest to (lub zawiera) niezmienny łańcuch zliczany z referencjami. To nigdy nie rzuci się na tworzenie kopii ani kopiowanie zadań.
I
explicit runtime_error(string&&);
może nigdy (efektywnie) Zasoby transferu z "typu 1" string do "typu 2" string.
Jak wyglądałby ciąg 2 typu, nie interesujący? (Jeśli jest to wewnętrzny, ukryty, zdefiniowany przez implementację typ wewnętrzny, to wystarczająca odpowiedź.) –
Może to wyglądać jak niezmutujące części bazującego na C++ 03 COW 'std :: string'. Rzeczywiście, właśnie to zrobiła libC++. Łańcuch typu 2 ma ABI identyczną z gcc-4.2 'std :: string', dzięki czemu' runtime_error' może być wyrzucony z biblioteki libC++ i złapany za pomocą libstdC++ (i vice versa) * w obrębie tej samej aplikacji *. –
Dlaczego chcesz to zrobić? –
- 1. Czy konstruktor kopiowania i kopia przypisania std :: runtime_error noexcept?
- 2. Różnica: std :: runtime_error vs std :: exception()
- 3. Dlaczego wywoływany jest konstruktor ruchu?
- 4. Jak poprawnie zdefiniować konstruktor ruchu?
- 5. Dlaczego nie został wywołany konstruktor ruchu std :: string?
- 6. Dlaczego wywołuje to konstruktor kopiowania, a nie konstruktor ruchu?
- 7. Jak zaimplementować konstruktor ruchu dla dziedziczenia w kształcie rombu?
- 8. kompilacji błąd podczas próby dziedziczą std :: runtime_error
- 9. Jawny konstruktor ruchu potrzebny w kontenerze?
- 10. Błąd z przechwytywaniem std :: runtime_error jako std :: wyjątek
- 11. Automatycznie generowany konstruktor ruchu z niezmiennymi elementami
- 12. Konstruktor za pomocą std :: naprzód
- 13. Dlaczego ten konstruktor kopiowania jest wywoływany, a nie konstruktor ruchu?
- 14. Czy konstruktor prywatnego ruchu uniemożliwia przeniesienie?
- 15. std :: regex konstruktor zgłasza wyjątek
- 16. Funkcja Lambda jako domyślny argument dla funkcji std :: in Konstruktor
- 17. C++ - utwórz nowy konstruktor dla std :: vector <double>?
- 18. Hałas Perlin dla ruchu?
- 19. boost filesystem :: konstruktor ścieżek std :: length_error
- 20. Przekazywanie std :: wektor do semantyki konstruktora i ruchu
- 21. Kiedy powinienem zadeklarować konstruktor ruchu bez żadnego wyjątku?
- 22. std :: unique_ptr :: reset i wyjątki konstruktor
- 23. Jawny konstruktor kopiowania i std :: sort
- 24. std :: make_shared STD :: unique_ptr i przenieść konstruktorzy
- 25. Dlaczego konstruktor ruchu nie jest wywoływany podczas poruszania się w lambda?
- 26. vector :: push_back nalega na użycie konstruktora kopiowania, chociaż konstruktor ruchu jest dostarczany
- 27. Czy std :: vector :: data() jest zachowywany w ruchu?
- 28. std :: back_inserter dla std :: set?
- 29. Wyłączanie konstruktora ruchu
- 30. Czy puste nawiasy wywołują domyślny konstruktor lub konstruktor pobierający std :: initializer_list?
Jeśli 'std :: runtime_error' miał konstruktor pobierający' std :: string && ', to z pewnością nie byłby konstruktorem ruchu. Konstruktor ruchu zajmie 'std :: runtime_error &&'. –
Nie jestem pewien, czy podążam: sądząc od początku wydaje się, że twoje pytanie dotyczy 'runtime_error', ale potem przełączasz się na' std :: string'. W jakim celu próbujesz dokonać? –
@AndyProwl: 'std :: runtime_error' może być teraz skonstruowany z' const std :: string & 'lub' const char * what_arg'. Pyta, dlaczego nie można go zbudować z 'std :: string &&'. –