我在C ++中使用g ++编写了一个非常简单的应用程序,我试图抛出一些原始string作为exception(是的,我知道,这不是一个好习惯)。
我有以下代码(简化):
int main() { try { throw "not implemented"; } catch(std::string &error) { cerr<<"Error: "<<error<<endl; } catch(char* error) { cerr<<"Error: "<<error<<endl; } catch(...) { cerr<<"Unknown error"<<endl; } }
我在控制台上遇到Unknow error
。 但是,如果我静态强制转换文字string为std :: string或char *它打印Error: not implemented
预期方式Error: not implemented
。 我的问题是:如果我不想使用静态转换,那么我应该捕获什么types?
你需要用char const*
而不是char*
来捕获它。 std::string
和char*
都不会捕获它。
捕捉限制了它匹配的类型的规则。 规范说(其中“CV”的意思是“常量/易变的组合”或他们都没有)。
处理程序是匹配类型为E的异常对象if
- 处理程序的类型为cv T或cv T&,E和T是相同的类型(忽略顶级cv限定符),或者
- 处理程序的类型是cv T或cv T,而T是E的明确的公共基类
该处理程序的类型为cv1 T * cv2,E是一个指针类型,可以通过以下两种方式之一转换为处理程序的类型:
- 一个标准的指针转换(4.10)不涉及到指向私有或受保护或模糊类的指针的转换
- 资格转换
一个字符串文字的类型为char const[N]
,但是抛出一个数组将会使数组衰退并且实际抛出一个指向它的第一个元素的指针。 所以你不能捕获一个由char*
引发的字符串,因为在匹配的时候,它需要匹配char*
到一个char const*
,这会抛出一个const(一个限定转换只允许添加 const) 。 字符串文字到char*
的特殊转换只在需要专门转换字符串时才被考虑。
尝试添加const
你正在捕捉的类型, const char*
(可能是const char* const
)。
字符串文字的确切类型是一个常量字符数组(因为包含了NUL终止符,所以在本例中为const char [15]
)。
类型应该是const char[15]
或者const char*
。
但是,虽然语言不禁止您抛出任何类型的值,但您不应该将原生数据类型作为异常提升。 相反,你想引发一个std::exception()
实例,或者创建你自己的异常类。
问题是你试图去捕捉一些常量。 以下将起作用:
catch(const char *错误){cerr
字符串文字的类型是char const *
。 为了与现有代码向后兼容,有一个(不建议使用的)转换为char *
(但是您仍然必须将其视为const
– 任何修改尝试都会给UB)。
因此,像这样的代码应该工作:
#include <iostream> using namespace std; int main() { try { throw "not implemented"; } catch(char const *error) { cerr<<"Error: "<<error<<endl; } return 0; }
查看标准规范第2.14.5节,它在3页上处理字符串文字的类型和种类。 不要做你刚开始做的事,只要说:
throw std::exception("not implemented");
以及适当的
catch (std::exception& pEx)
这种“正常”的方法有什么问题吗?