Переместить конструктор для 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 (и вперед) содержит две реализации строк:

  1. std::string: Обычно это тип, оптимизированный для коротких строк, с конструктором копирования и назначением копирования, способным генерировать исключения.

  2. std::runtime_error: Это (или содержит) неизменяемая строка с подсчетом ссылок. Это никогда не приведет к созданию копии или назначению копирования.

А также

explicit runtime_error(string&&);

никогда не может (эффективно) передавать ресурсы из строки "тип 1" в строку "тип 2".

Другие вопросы по тегам