Why does std::runtime_error not provide a constructor accepting an std::string&&? Looking at the constructors for std::string, it has a move constructor, but the noexcept specification is only there for C++14, not C++11. Was this a mistake, a deadline that was missed or am I missing something?
explicit runtime_error(string&&);
does not exist simply because it would not provide any optimization.
As it turns out, a C++11-conforming runtime_error does not internally store a std::string.  The reason is that the copy members of runtime_error must not throw exceptions.  Otherwise the wrong exception could get thrown when the compiler copies the exception object in the process of throwing it.
This implies that runtime_error needs to store a non-mutable reference counted string.  However C++11 outlaws the COW-implementation for std::string.  Implementations of std::string have moved to a "short-string-optimization" which must allocate on copy construction if the length of the string is beyond the "short limit".  And there is no limit on the length of strings used to construct a runtime_error.
So effectively C++11 (and forward) contains two implementations of strings:
std::string : This is typically a short-string-optimized type with a copy constructor and copy assignment that is capable of throwing exceptions.
std::runtime_error :  This is (or holds) an immutable reference-counted string.  This will never throw on copy construction or copy assignment.
And
explicit runtime_error(string&&);
can never (efficiently) transfer resources from the "type 1" string to the "type 2" string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With