noexcept оператор проверки времени компиляции - PullRequest
1 голос
/ 04 мая 2020

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

void may_throw();

// ERROR: expression must have bool type or be convertible to bool
void check () noexcept(may_throw());

int main()
{
    // works just fine!
    std::cout << noexcept(may_throw());
}

Вопрос в том, как проверить, если функция генерирует без изменение прототипа функции для условного указания noexcept?

Я не могу изменить прототип функции, потому что дело в том, чтобы проверить, если функция не выдает, если она должна возвращать true или false.

РЕДАКТИРОВАТЬ

Я пытаюсь высмеять noexcept, но похоже, что он не работает для макросов.

#include <iostream>

#if 0
#define ASDF(...) (void)0
#else
#define ASDF(...) throw 1
#endif

void check() noexcept(noexcept(ASDF()))
{
    // wrong!
    // std::cout << noexcept(noexcept(ASDF()));

    // edit: it should be this, and it works.
    // (tnx: StoryTeller-UnslanderMonica)
    std::cout << noexcept(ASDF());
    ASDF(0);
}

int main()
{
    check();
}

Ответы [ 2 ]

3 голосов
/ 04 мая 2020

Учитывая void check () noexcept(may_throw());, noexcept Specifier ожидает выражение, конвертируемое в bool, в то время как may_throw() возвращает void и не может преобразоваться в bool.

You следует применить оператор noexcept к may_throw() и указать его для спецификатора noexcept. то есть

// whether check is declared noexcept depends on if the expression
// may_throw() will throw any exceptions
void check () noexcept(noexcept(may_throw()));
//            ^^^^^^^^          -> specifies whether check could throw exceptions 
//                     ^^^^^^^^ -> performs a compile-time check that returns true if may_throw() is declared to not throw any exceptions, and false if not.
2 голосов
/ 04 мая 2020

Правильный способ сделать это:

noexcept( noexcept( may_throw() ) )

Почему первый noexcept определяется как noexcept-specifier. Это используется для определения, является ли функция noexcept или нет. Он имеет вид (от [except.spec]):

noexcept-specifier:
    noexcept ( constant-expression )
    noexcept
    throw ( )

Вторым является noexcept-operator: Оператор noexcept определяет, является ли вычисление его операнда, который является неоцененным операндом (8.2 ), может выдать исключение (18.1). из [expr.unary.noexcept]

...