假设我有./script.sh: line 5: syntax error near unexpected token `$'{\r''
'/script.sh: line 5: `foo(){
个实例。我需要检查底层异常是否属于某种类型(理想情况下可以访问它)。它可以这样做:
std::exception_ptr
有更好的方法吗?
是否有保证std::exception_ptr p = ...;
try
{
std::rethrow_exception(p);
}
catch(MyType const& x)
{
...
}
catch(...)
{
// do smth else
}
无法复制基础异常,从而导致抛出std::rethrow_exception
等问题?
答案 0 :(得分:0)
std::rethrow_exception
是检索底层异常对象的唯一方法,因此必须使用它。假设每个例外都是从std::exception
继承而来的,那么你就可以做出动态广播' 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);
}
}
}