luc*_*nte 7 c++ boost exception
使用时boost::exception,了解异常所携带的数据的首选方法是什么?在boost文档中,给出了以下示例:
catch( io_error & e )
{
std::cerr << "I/O Error!\n";
if( std::string const * fn=get_error_info<file_name>(e) )
std::cerr << "File name: " << *fn << "\n";
if( int const * c=get_error_info<errno_code>(e) )
std::cerr << "OS says: " << strerror(*c) << "\n";
}
Run Code Online (Sandbox Code Playgroud)
这似乎有点尴尬,特别是如果异常冒泡了很多层并且理论上可以获得大量元数据.因此,我认为记录每个异常类的可能错误信息是有意义的.然后我可能还需要一些函数的文档,关于异常中可能包含的信息.最后我觉得我在文档中有完全相同的结构,就像我在代码中使用的那样,如果我只使用类似下面的结构:
struct FileException {
string* filename; // NULL or string
}
Run Code Online (Sandbox Code Playgroud)
然后我可以在catch块中更改此信息:
catch (FileException& e) {
e.filename = filename;
throw;
}
Run Code Online (Sandbox Code Playgroud)
这种简单的方法可以解决大部分文档,并从所有安全性中获益(例如,不尝试从中获取文件名MathException).然而人们使用提升.我缺少动态方法的一大优势吗?如何记录代码中的错误信息?
如果您可以更改或设计异常以包含描述错误所需的内容,请按照您的意愿进行操作。但是如果您的代码没有生成异常,或者您在生成错误时无法访问错误信息,那么您需要error_info. 例如,我们有一个read自由函数,可以从不包含文件名的 C++ 文件对象中读取数据,如下所示:
void read( file& fp, std::vector<unsigned char>& buf ) {
if( fread(&buf[0], 1, buf.size(), fp.getFile()) == -1 ) {
// I don't know the file name, what should I do here??
boost::throw_exception( io_error() );
}
}
try {
file fp( "/path/to/file" );
// do some thing with fp
read( fp, buffer );
} catch( io_error& e ) {
e << file_name( "/path/to/file" ); // here I can provide file name
throw;
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,error_info设计的目的是我必须增量地将数据添加到错误中,但是如果在抛出站点上我拥有所有必需的信息,那么我可以将这些信息嵌入到异常类中并避免使用error_info