I mistakenly pasted a throw
statement after a return
with the following final result:
void DXManager::initialize(const std::shared_ptr<nae::Context>& ctx_ptr)
{
// ...
if (FAILED(result))
{
return throw std::exception("Failed to enumerate display mode list");
}
// ...
}
I successfully built the solution before noticing the mistake, and I'm curious which specification allows the syntax above.
By reading cppreference.com (under Notes), I see
The throw-expression is classified as prvalue expression of type void. Like any other expression, it may be a sub-expression in another expression, most commonly in the conditional operator:
double f(double d) { return d > 1e7 ? throw std::overflow_error("too big") : d; } // ...
but I'm not quite sure it's what I'm looking for.
Well, it's because a return statement in a function returning void
, can have a void
operand:
The expr-or-braced-init-list of a return statement is called its operand [...] A return statement with an operand of type
void
shall be used only in a function whose return type is cvvoid
.
And as you found out yourself, a throw
expression has type void
. This provision is there to make writing generic code smoother. Consider this:
template<typename T>
T foo() {
return T();
}
The above rule (along with another rule that defines void()
) make the above template valid even when instantiated for void
.