Есть ли «безопасный» способ объявить функцию lippincott, чтобы она не вызывалась вне catch? - PullRequest
4 голосов
/ 13 марта 2019

A Функция Липпинкотта - это функция, которая преобразует исключение в код возврата, который можно безопасно обрабатывать при обратном вызове из другого языка, который не поддерживает исключения, такие как C. Такие функции, потому что они намеренно использовать throw без аргумента, тем самым перебрасывая последнее обнаруженное исключение, нельзя вызвать вне контекста catch блока.

Мне интересно, есть ли в современном C ++ (c ++ 17 или c ++ 20) какой-либо механизм объявления для конкретной идентификации таких функций и обеспечения того, что функция вызывается только из контекста блока catch (или из контекста другой такой функции), генерируя ошибку времени компиляции, если она вызывается из любого другого контекста.

Ответы [ 2 ]

4 голосов
/ 13 марта 2019

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

Однако вы можете вызвать std::current_exception() из вашей функции Lippincott, чтобы определить, обрабатывается ли в данный момент исключение. Если это возвращает nullptr, то нет активных исключений. Затем вы можете обработать это во время выполнения, вызвав assert и / или вернув функцию (и не используя throw).

1 голос
/ 13 марта 2019

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

Вы можете использовать программирование более высокого порядка и вместо обеспечения функции lippincott предоставить оболочку, которая выполняет весь try-call-catch-lippincott для данной функции:

auto with_catch = [](auto&& f, auto&& c, auto&&... args) -> decltype(c()) {
    try {
        f(std::forward<decltype(args)>(args)...);
        return {};
    } catch (...) {
        return c();
    }
};

auto with_lippincott = [](auto&& f, auto&&... args) {
    return with_catch(
        std::forward<decltype(f)>(f),
        lippincott,
        std::forward<decltype(args)>(args)...
    );
};

Это не так просто неправильно использовать.Пример использования:

foo_Result r3 = with_lippincott(Snafuscate, true);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...