gpt4 book ai didi

c++ - 是否可以检查给定的 exception_ptr 实例是否拥有某种类型的异常?

转载 作者:太空狗 更新时间:2023-10-29 23:12:33 26 4
gpt4 key购买 nike

假设我有一个 std::exception_ptr 实例。我需要检查底层异常是否属于某种类型(理想情况下可以访问它)。可以这样做:

std::exception_ptr p = ...;
try
{
std::rethrow_exception(p);
}
catch(MyType const& x)
{
...
}
catch(...)
{
// do smth else
}

有没有更好的办法?

是否可以保证 std::rethrow_exception 不会复制导致抛出 std::bad_alloc 等问题的底层异常?

最佳答案

std::rethrow_exception 是检索底层异常对象的唯一方法,因此必须使用它。假设每个异常都继承自 std::exception,您可以创建“dynamic_cast”if-else 链。我已经用虚拟异常尝试过它并且它有效。如果更好-这是品味问题。在这种方法中,更容易拥有一些共享上下文或做两种情况或在两种类型的情况下做某事。

你的问题中更有趣的部分是关于复制对象——根据 C++ 引用 std::exception_ptr “是一个类似共享指针的类型”,所以不应该发生复制。虽然,我制作了简单的测试用例,它确实在 Visual Studio 2017 中被复制了。它在 GCC 中运行良好。我没有关于其他编译器的信息。

#include <cstdio>
#include <string>
#include <exception>

class A :public std::exception
{
public:
};


class B :public std::exception
{
public:
virtual const char* what() const
{
return "B";
}
B() { printf("Created B at %X\n", this); }
B(const B& b) { printf("Copied B from %X at %X\n", &b, this); } // make it copyable
B& operator=(const B& b) { printf("Copied B from %X at %X\n", &b, this); return *this;}; // make it copyable
B(const B&& b) { printf("Moved B from %X at %X\n", &b, this); } // make it movable

};

class C : public B
{
public:
int q;

C(int qq) { q = qq; printf("Created C at %X with q=%d\n", this, q); }
C(const C& c) :B(c) { q = c.q; printf("Copied C from %X at %X\n", &c, this); } // make it copyable
C& operator=(const C& c) { q = c.q; printf("Copied C from %X at %X\n", &c, this); return *this; }; // make it copyable
C(const C&& c):B(std::move(c)) { q = std::move(c.q); printf("Moved C from %X at %X\n", &c, this); } // make it movable
};

int main()
{
// Check does rethrow_exception copies underlying object
try
{
B b; // B created
throw std::move(b);
}
catch (...)
{
auto p = std::current_exception();
try
{
std::rethrow_exception(std::move(p));
}
catch (...)
{
auto p = std::current_exception();
try
{
std::rethrow_exception(p);
}
catch (B& b) // refered to last copy
{
printf("done with B at %X\n", &b);
}
}
}


printf("\n");
// Try with dynamic_cast
try {
C c(12);
throw std::move(c);
}
catch (...)
{
printf("Caught something\n");
auto p = std::current_exception();
try {
std::rethrow_exception(p);
}
catch (std::exception& ex)
{
printf("Caught ex\n");
if (A* a = dynamic_cast<A*>(&ex))
printf("ex is A\n");
if (B* b = dynamic_cast<B*>(&ex))
printf("ex is B\n");
if (C* c = dynamic_cast<C*>(&ex))
printf("ex is also C with q=%d\n", c->q);
}
}
}

关于c++ - 是否可以检查给定的 exception_ptr 实例是否拥有某种类型的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45497765/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com