Почему return throw std::exception() принимается в функции void?

Я по ошибке вставил throw заявление после return со следующим конечным результатом:

void DXManager::initialize(const std::shared_ptr<nae::Context>& ctx_ptr)
{
    // ...

    if (FAILED(result))
    {
        return throw std::exception("Failed to enumerate display mode list");
    }

    // ...
}

Я успешно построил решение, прежде чем заметил ошибку, и мне любопытно, какая спецификация допускает приведенный выше синтаксис.


Читая cppreference.com (под примечаниями), я вижу

Выражение throw классифицируется как выражение prvalue типа void. Как и любое другое выражение, оно может быть подвыражением в другом выражении, чаще всего в условном операторе:

double f(double d)
  {
      return d > 1e7 ? throw std::overflow_error("too big") : d;
  }
  // ...

но я не совсем уверен, что это то, что я ищу.

1 ответ

Решение

Ну, это потому, что оператор возврата в функции, возвращающей voidможет иметь void операнд:

[stmt.return] / 2

Выражение expr-or-braced-init-list оператора return называется его операндом [...] Оператор return с операндом типа void должен использоваться только в функции с типом возвращаемого значения cv void,

И как вы узнали сами, throw выражение имеет тип void, Это положение сделано для того, чтобы сделать общий код более плавным. Учти это:

template<typename T>
T foo() {
    return T();
}

Вышеуказанное правило (вместе с другим правилом, которое определяет void()) сделать приведенный выше шаблон действительным даже при создании экземпляра для void,

Другие вопросы по тегам