I can't imagine a function which returns shared_ptr<T> *and* which could fail, to return an empty one in case of success. That said, in that case all it means is that you can't use throw_ directly in a return expression; or you could partially specialize throw_return<> for a specific type of shared_ptr, if that's appropriate.
On 13/06/2017 21:39, Emil Dotchevski wrote: private: void create_X_if_needed() noexcept { if (!m_X) { try { m_X = make_shared<X>(); } catch (internal_error const& e) { throw_(e.code()); } } } public: shared_ptr<X> get_X_if_enabled() noexcept { if (feature_X_enabled()) { create_X_if_needed(); } return m_X; } get_X_if_enabled() could return an empty pointer in two cases: 1. If feature_X_enabled() returns false during all calls, this is a successful return with no pointer. 2. If X's constructor throws an internal_error, this is an error code return with no pointer.
Regardless, the correct way to check for errors is to see if the result is valid. This is the price one must pay when not using exception handling.
Isn't the correct way to check for errors (without explicitly catching
errors) in this case to call has_current_error()?
Granted in this case get_X_if_enabled doesn't actually need to
explicitly check for errors since the following statements will work
regardless of whether there was an error state or not. But say if it
wanted to do some logging only in the case where create_X_if_needed
didn't fail, that would have to be written something like this:
shared_ptr<X> get_X_if_enabled() noexcept
{
if (feature_X_enabled())
{
create_X_if_needed();
if (!has_current_error())
{
log("has X");
}
}
return m_X;
}
The other possibility is to catch and rethrow the error, but that seems
more cumbersome and error-prone.
(Related: if the original throw_ was a custom type not derived from
std::exception, and catch<> is used to catch it as a std::exception and
throw_ it again, can it still be caught later with a
catch_