BOOST_SCOPE_EXIT

トップページ > 小道具 >

abstract

必要なヘッダ
<boost/scope_exit.hpp>
出来ること
スコープ終了時処理
リファレンス
en

sample

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

#include <iostream>
#include <vector>
#include <numeric>
#include <boost/foreach.hpp>
#include <boost/scope_exit.hpp>
using namespace std;

void f( vector<int>& v1, vector<int>& v2 )
{
	// v1 に 値を push
	v1.push_back(v1.size());

	// f を抜けるときに戻す
	BOOST_SCOPE_EXIT( (&v1) )
	{
		v1.pop_back();
	}
	BOOST_SCOPE_EXIT_END

	// v2 に 値を push
	v2.push_back(v2.size());

	// f を抜けるときに戻す
	BOOST_SCOPE_EXIT( (&v2) )
	{
		v2.pop_back();
	}
	BOOST_SCOPE_EXIT_END

	// 適当になにか処理
	if( accumulate(v1.begin(), v1.end(), 0) > 10 )
		throw "exception-1!";
	if( accumulate(v2.begin(), v2.end(), 0) > 10 )
		throw "exception-2!";
	cout << "ok" << endl;
}

int main()
{
	vector<int> v1; v1.push_back(1); v1.push_back(2);
	vector<int> v2; v2.push_back(3); v2.push_back(4);

	try { f(v1, v2); } catch(const char* e) {cout << e << endl;}
	BOOST_FOREACH(int a, v1) { cout << a << " "; } cout << endl;
	BOOST_FOREACH(int a, v2) { cout << a << " "; } cout << endl;

	v1.push_back(0);
	v2.push_back(1);

	try { f(v1, v2); } catch(const char* e) {cout << e << endl;}
	BOOST_FOREACH(int a, v1) { cout << a << " "; } cout << endl;
	BOOST_FOREACH(int a, v2) { cout << a << " "; } cout << endl;
}

ちょっと人工的な例ですが…

出力結果

ok
1 2
3 4
exception-2!
1 2 0
3 4 1

2回目は、3+4+1+3が10を越えるので例外が飛んでいますが、fから例外で戻ってくるときにはf内でpushした 3はちゃんとpopされていて、表示は3 4 1になっています。

etc

いわゆる try~catch~finally の finally というか、 D言語のscope(exit)文 のC++によるライブラリ実装です。 例外で抜けるかreturnやその他正常終了で抜けるかに関わらず、 スコープの終わりに必ず実行したい処理(リソースの後始末等)を書くことができます。 公式ドキュメントの Alternatives や、D言語リファレンスの 例外安全なプログラミング で、finally や RAII などの近い言語機能との比較がなされています。

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