boost::exception

トップページ > 小道具 >

abstract

必要なヘッダ
<boost/exception.hpp>
出来ること
例外にエラー情報を載せる汎用フレームワーク
リファレンス
en

sample

サンプルの動作確認バージョン [GCC4.4/1.41.0] [VC9/1.41.0]

#include <iostream>
#include <string>
#include <stdexcept>
#include <boost/exception.hpp>
using namespace std;

// 例外クラスを boost::exception を継承して定義すると…
class MyException
	: public boost::exception, public std::exception {};

// operator<< でエラー情報を追加できる
void h()
{
	BOOST_THROW_EXCEPTION( MyException() ); // throw MyException() << ファイル名や行番号情報; の省略用マクロ
}

typedef boost::error_info<struct tag_errno, int> errno_info; // int型のエラー情報

void g()
{
	try { h(); } catch( boost::exception& e )
	{
		e << errno_info(1234); // エラー情報を足して再throw
		throw;
	}
}

typedef boost::error_info<struct tag_errmsg, string> errmsg_info; // string型のエラー情報

void f()
{
	try { g(); } catch( boost::exception& e )
	{
		e << errmsg_info("some bad thing happened"); // エラー情報を足して再throw
		throw;
	}
}

int main()
{
	try { f(); } catch( boost::exception& e )
	{
		cout << diagnostic_information(e) << endl; // 表示

		cout << *boost::get_error_info<errno_info>(e) << endl; // 個別に表示
	}
}

出力例

Dynamic exception type: class MyException
[struct boost::type<struct tag_errmsg>] = some bad thing happened
[struct boost::type<struct tag_errno>] = 1234
[struct boost::type<struct boost::tag_throw_file>] = test.cpp
[struct boost::type<struct boost::tag_throw_function>] = void __cdecl h(void)
[struct boost::type<struct boost::tag_throw_line>] = 14

1234

etc

例外に載っけるエラー情報は、レイヤー毎に詳細度が違ったりします。 Boost.Exception の公式のリファレンスに載っている例では、 「ファイル処理のエラーで、 例外発生部分ではファイルハンドルしかわからないのでファイル名の情報を 例外に入れられないが、1個上の関数ならファイル名も入れられる」 のようなのがあがっていました。 こういう場合に、レイヤー毎に何重にもラップした例外を放ったり、 あるいは全て文字列化して例外メッセージにつなげたりするのではなく、 ひとつのエラー情報伝達フレームワークで扱ってしまおう!というのがBoost.Exceptionです。

boost::expcetion を継承した例外クラスには、 error_info で囲んだ任意の型のエラー情報を載せることができます。 スレッドを超えて例外を飛ばす場合のデータの所有権管理などもうまいことやってくれる模様。 また、既存の例外オブジェクト/例外階層に潜り込んで情報載せを可能にする enable_error_info なども用意されています。

presented by k.inaba (kiki .a.t. kmonos.net) under CC0