Reputation: 930
According to cppreference.com, one of the c'tors of std::runtime_error
has the following signature:
explicit runtime_error( const std::string& what_arg );
However (I assume) the freshly constructed exception object is required to hold a copy of that std::string
argument anyways. So why is the argument given by const ref (rather than by value)?
Is my assumption wrong?
Upvotes: 1
Views: 859
Reputation: 54345
You should always take the string as a const reference. It avoids making two copies of it.
If you accepted it as a string, it would have to first construct it. Then when putting it into a class member, it would have to copy construct it.
This may not be so inefficient with move operations but some of us still have to write C++ code for Visual Studio 2008, or Redhat Linux 5, and can't use C++11, 14 or 17.
And besides that, when std::exception was created there weren't any move operations in the C++ standard.
Upvotes: 2
Reputation: 3321
Pass by value wouldn't be useful anyway. You might be thinking about passing a std::string&&
, though. According to the cppreference.com page you posted.
Because copying std::exception is not permitted to throw exceptions, this message is typically stored internally as a separately-allocated reference-counted string. This is also why there is no constructor taking std::string&&: it would have to copy the content anyway.
std::runtime_error
is not supposed to hold a std::string
because if it did, copying the exception could result in another exception due to failure to allocate space for a copy. One way to sidestep this is to use a reference counted buffer and copy the argument to that buffer. Given that a copy has to be made, an std::string&&
overload provides no benefit.
Upvotes: 6