我正在使用Linux下的g ++编写一个非常简单的C ++应用程序,我试图将一些原始字符串作为异常(是的,我知道,这不是一个好习惯)。
我有以下代码(简化):
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
。但是,如果我将文字字符串静态转换为std::string
或char *
,则会按预期打印Error: not implemented
。我的问题是:如果我不想使用静态强制转换,那么我应该捕获的类型是什么?
答案 0 :(得分:29)
您需要使用char const*
代替char*
来抓住它。 std::string
和char*
之类的任何内容都无法捕捉到它。
捕获限制了与其匹配的类型的规则。规范说(其中“cv”表示“const / volatile组合”或两者都不是。)
处理程序是E类型的异常对象的匹配,如果
- 处理程序的类型为cv T或cv T&amp;和E和T是相同的类型(忽略顶级cv限定符),或
- 处理程序的类型为cv T或cv T&amp;和T是E的明确的公共基类,或
处理程序的类型为cv1 T * cv2,E是一种指针类型,可以通过其中一个或两个转换为处理程序的类型
- 标准指针转换(4.10),不涉及转换为指向私有或受保护或模糊类的指针
- 资格转换
字符串文字的类型为char const[N]
,但抛出数组会使数组衰减并实际抛出指向其第一个元素的指针。因此,您无法通过char*
捕获抛出的字符串文字,因为在匹配时,它需要将char*
与char const*
匹配,这将丢弃一个const(一个限定条件)转换只允许添加 const)。只有当您需要专门转换字符串文字时,才会考虑将字符串文字特殊转换为char*
。
答案 1 :(得分:10)
尝试将const
添加到您捕获的类型const char*
(可能是const char* const
)。
答案 2 :(得分:4)
字符串文字的确切类型是一个const字符数组(const char [15]
为您的示例,因为包含了NUL终结符)。抛出时,数组衰减到const char*
,这与长度无关。
答案 3 :(得分:1)
类型应为const char[15]
或const char*
。
但是,虽然该语言不禁止您抛出任何类型值,但您不应将本机数据类型提升为异常。相反,您希望引发std::exception()
实例,或创建自己的异常类。
答案 4 :(得分:1)
问题在于你正试图捕捉一些const的东西。以下内容适用:
catch(const char * error) { CERR答案 5 :(得分:1)
字符串文字的类型为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;
}
答案 6 :(得分:1)
查看标准规范的2.14.5节,它在3页上处理字符串文字的类型和种类。不要做你刚开始做的事,只要说:
throw std::exception("not implemented");
以及正确的
catch (std::exception& pEx)
这种“正常”方法有问题吗?