I’m writing a small library that does some things that could have an exception thrown when an input argument is out of range. Seems straightforward that I would throw a std::out_of_range.
I would also like to generate a nice message, such as “You gave me X but Y is the maximum value in range” – i.e. I’m formatting a string and wish to use that for the exception.
What is odd is that the signature of the constructor is
explicit out_of_range (const string& what_arg)
That is, it takes a const reference to the string. Any string that I create on the stack will be destroyed as we pop out of the function, leaving a mangled heap of garbage for the catcher of the exception. so I have only a few options:
- Use a string literal, so no nice generated message. It’s valid for the lifetime of the program.
- Make the string static in the function and rewrite it when thrown. Thread safety is not an issue for my program, but this feels way dirty.
- Subclass out_of_range so that it takes a copy of string, and call the superclass constructor with a reference to the copy, such that the copy exists for the lifetime of the exception object.
I’m leaning toward 3 as the least gross, and arguably a better design than directly using the standard class anyway, but I have to ask: is there really no way to use the standard out_of_range class directly with a generated string? Am I missing something?
The exception will hold a copy of the string you passed in, not just a reference. You can safely create the string locally and pass it to the constructor of the exception without worrying about lifetime issues.
Note that the fact that the string is passed by reference does not inhibit the possibility of copying inside the constructor, which seems to have confused you.