I am thinking about writing non-copyable exception classes. I find it interesting, because then I don't have to worry about exceptions that could be thrown during allocations within the copy-constructor. If the creation of the exception object succeeds, everything is fine and there should be no issues with std::terminate.
struct exception
{
exception() = default;
exception(const exception&) = delete;
exception(exception&&) noexcept = default;
~exception() noexcept = default;
auto operator=(const exception&) -> exception& = delete;
auto operator=(exception&&) noexcept -> exception& = delete;
};
int main()
{
try {
try {
throw exception{};
} catch (...) {
std::rethrow_exception(
std::current_exception());
}
} catch (const exception& e) {
return 1;
}
}
GCC-4.7 and Clang-3.2 accept the above code. However, I am a bit surprised. As far as I know, there are several situations where exception objects might be copied, e.g. std::current_exception() and std::rethrow_exception().
Question: Is the above code correct according to C++11, i.e. will it be accepted by all compilers conforming to C++11?
Edited: Added std::rethrow_exception and std::current_exception to the example. Both compilers accept this version. This should make it clear, that if the compiler doesn't require a copy-constructor when an exception is thrown, the compiler won't require one when these two functions are used.
current_exception says it refers either to the current exception or to a copy of it it, but doesn't say which. This suggests to me that:
current_exception on it)Just throwing the thing and catching it by reference is fine. The temporary in the throw expression is "used to initialize" the object used by the implementation to keep the current exception, so it can be moved or copied (according to which the class supports), and that move/copy can be elided.
For what it's worth, make_exception_ptr is specified to always copy. You could perhaps argue that this is a defect: e can be a by-value parameter in which case moving might be better. But that's my impetuous and ignorant impression, I've never even seen these functions before now.
[*] It's explicitly unspecified whether or not current_exception "creates a new copy each time it's called", but I'm not wholly certain whether that is intended to imply that it's unspecified whether it creates a new copy the first time it's called.
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