C++ Logo

std-proposals

Advanced search

[std-proposals] operator throw

From: Yexuan Xiao <bizwen_at_[hidden]>
Date: Tue, 18 Jun 2024 17:02:17 +0000
Hello everyone,
I’ve recently come up with a new idea and I’m looking for some feedback and opinions.

Currently, when using exceptions derived from std::exception and the status_code from P1028, it’s common to need to convert error values into exception objects.
For example:

// status_code and make_status_code from P1028 std::status_code

By calling the conversion constructor:

throw class_derived_from_std_exception(error_code::item);
throw status_code<domain_type>(error_code::item);

Or by using a type conversion function:

etype to_etype(error_code c) noexcept;
generic_code make_status_code(errc c) noexcept;

throw to_etype(error_code::item);
throw make_status_code(errc::succeed);

Or by using a helper function to throw an exception:

void throw_exception(error_code e) {
    throw type_derived_from_std_exception(error_code::item);
}

throw_exception(error_code::item);

C++ currently lacks a best practice for converting error codes into exception objects.

Therefore, I propose adding user-defined operator throw overload to implement automatic conversion from error codes to exception objects.

This idea is inspired by the existing operator co_await in C++, which facilitates the construction of awaiters for us.

Currently, my design is as follows:

The operator throw can be defined as both a member function and a non-member function, where the member function version has no parameters, and the non-member function version has a single parameter.

The expression throw expr;

will first attempt

expr.typename std::remove_reference<decltype(expr)>::operator throw()

and use its result as the operand for the throw expression

If that call is not viable, then it will attempt

operator throw(expr)

and use its result as the operand for the throw expression

If that’s still not viable, then expr itself is the operand for the throw expression.

The catch block is unaffected. I believe the relationship between throw and catch should be reflected in documentation, similar to operator co_await. And this conversion can only occur once, just like operator co_await.

Additionally, F. v.S. pointed out that this design has an extra side effect: if operator throw is overloaded as a member function, then the class can never be the actual type of an exception. Based on this, by avoiding defining operator throw(), or by adding =delete to it, can prevent objects of that class from being thrown as exception objects.

Received on 2024-06-18 17:02:27