plats1
plats1

Reputation: 930

Why does the c'tor of std::runtime_error take a constant reference to std::string?

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

Answers (2)

Zan Lynx
Zan Lynx

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

patatahooligan
patatahooligan

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

Related Questions