Почему return throw std :: exception () принимается в функции void? - PullRequest
0 голосов
/ 28 августа 2018

Я ошибочно вставил оператор 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 Ответ

0 голосов
/ 28 августа 2018

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

[stmt.return] / 2 * +1008 *

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

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

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

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

...