文章目录
🐾前言
从 C++11 其有 std::uncaught_exception
用于判断++当前线程++ 是否有未捕获的异常。而这个函数只是返回 bool
仅能查看是否存在未捕获异常。
因此到了 C++17 被弃用,在 C++20 中移除。C++17 引入了 int std::uncaught_exceptions()
可以获得具体的数量。
std::uncaught_exception, std::uncaught_exceptions - cppreference.com
🐾实例
🪝工具类
其实这个非常简单,最常用的就是在析构函数的时候,进行获取判断。
因此可以写这么一个工具类。当然,是选择在判断出有异常还是没异常的时候触发这个 action 还是两种状态下都注册一个,都是可以的。
cpp
#include <exception>
#include <functional>
class ExcCatch {
private:
const int count = 0;
std::function<void()> action;
public:
ExcCatch(const std::function<void()>& action = {})
: count(std::uncaught_exceptions()), action(action) {}
~ExcCatch() {
if (count != std::uncaught_exceptions()) {
if (action) {
action();
}
}
}
};
🪝测试
此处是用 vscode 中的 Copilot 所生成的测试代码。
简单看看使用方式就行了。
cpp
#include <exception>
#include <functional>
class ExcCatch {
private:
const int count = 0;
std::function<void()> action;
public:
ExcCatch(const std::function<void()>& action = {})
: count(std::uncaught_exceptions()), action(action) {}
~ExcCatch() {
if (count != std::uncaught_exceptions()) {
if (action) {
action();
}
}
}
};
#include <atomic>
#include <iostream>
#include <stdexcept>
// Helper for test output
#define ASSERT_TRUE(cond, msg) \
if (!(cond)) { \
std::cout << "[FAIL] " << msg << std::endl; \
} else { \
std::cout << "[PASS] " << msg << std::endl; \
}
#define ASSERT_FALSE(cond, msg) ASSERT_TRUE(!(cond), msg)
// Test that ExpCatch does not call action if no exception is thrown
void test_NoException_ActionNotCalled() {
std::atomic<bool> called{false};
{
ExcCatch guard([&] { called = true; });
}
ASSERT_FALSE(called, "NoException_ActionNotCalled");
}
// Test that ExpCatch calls action if exception is thrown
void test_Exception_ActionCalled() {
std::atomic<bool> called{false};
try {
ExcCatch guard([&] { called = true; });
throw std::runtime_error("test");
} catch (...) {
// Exception is caught here
}
ASSERT_TRUE(called, "Exception_ActionCalled");
}
// Test that ExpCatch works with empty action
void test_EmptyAction_NoCrash() {
try {
ExcCatch guard;
throw std::runtime_error("test");
} catch (...) {
// Should not crash
}
std::cout << "[PASS] EmptyAction_NoCrash" << std::endl;
}
// Test that ExpCatch does not call action if exception is thrown but not caught in scope
void test_ExceptionNotCaughtInScope_ActionCalled() {
std::atomic<bool> called{false};
auto test_func = [&] {
ExcCatch guard([&] { called = true; });
throw std::runtime_error("test");
};
try {
test_func();
} catch (...) {
// Exception is caught here
}
ASSERT_TRUE(called, "ExceptionNotCaughtInScope_ActionCalled");
}
int main() {
test_NoException_ActionNotCalled();
test_Exception_ActionCalled();
test_EmptyAction_NoCrash();
test_ExceptionNotCaughtInScope_ActionCalled();
return 0;
}
⭐END
🌟交流方式
关注我,学习更多C/C++,python,算法,软件工程,计算机知识!
⭐交流方式⭐ |C/C++|算法|设计模式|软件架构-CSDN社区
B站👨💻主页:天赐细莲 bilibili