2015-01-18 15 views
9

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

+0

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 &&'. –

+0

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ć? –

+0

@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 &&'. –

Odpowiedz

14

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:

  1. 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.

  2. 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.

+1

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ź.) –

+5

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 *. –

+0

Dlaczego chcesz to zrobić? –

Powiązane problemy