Переместить конструктор для std::runtime_error
Почему std::runtime_error
не предоставлять конструктор, принимающий std::string&&
? Глядя на конструкторов дляstd::string
, у него есть конструктор перемещения, но noexcept
Спецификация существует только для C++14, но не для C++11. Было ли это ошибкой, пропущенным сроком или я что-то упустил?
1 ответ
explicit runtime_error(string&&);
не существует просто потому, что не обеспечит никакой оптимизации.
Как оказалось, C++11-соответствующий runtime_error
не хранит внутренне std::string
, Причина в том, что члены копии runtime_error
не должны бросать исключения. В противном случае может возникнуть неправильное исключение, когда компилятор копирует объект исключения в процессе его выброса.
Это подразумевает, что runtime_error
необходимо хранить неизменяемую строку с подсчетом ссылок. Однако C++ 11 запрещает реализацию COW для std::string
, Реализации std::string
перешли к "оптимизации короткой строки", которая должна выделяться при создании копии, если длина строки превышает "короткий предел". И нет никаких ограничений на длину строк, используемых для создания runtime_error
,
Таким образом, C++11 (и вперед) содержит две реализации строк:
std::string
: Обычно это тип, оптимизированный для коротких строк, с конструктором копирования и назначением копирования, способным генерировать исключения.std::runtime_error
: Это (или содержит) неизменяемая строка с подсчетом ссылок. Это никогда не приведет к созданию копии или назначению копирования.
А также
explicit runtime_error(string&&);
никогда не может (эффективно) передавать ресурсы из строки "тип 1" в строку "тип 2".