Why does std::runtime_error
not provide a constructor accepting an std::string&&
? Looking at the constructors for std::string, it has a move co
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.