暗黙のエラーチェックを実現する

動機

APIなんかで、よく

bool GetSomeValue(type param1,type param2,type* result);

式の関数を見かける。引数で結果を格納する場所を渡し、「成功したかどうか」を返値とするやつ。
エラー処理をまじめにやると

bool result;
type value;
result=GetSomeValue(1,2,&value);
if(!result) { /* エラー処理 */ }
result=DoSomething("hoge","hage",value);
if(!result) { /* エラー処理 */ }
result=DoAnotherSomething(value);
if(!result) { /* エラー処理 */ }
//...

といったかんじになって大変うざいわけですね。

提案手法

class unchecked_error {};
struct succeed {
	succeed(bool succeed):succeed_(succeed),checked_(false) {}
	operator bool() {
		checked_=true;
		return succeed_;
	}
	~succeed() {
		if(!succeed_ && !checked_)
			throw unchecked_error();
	}
private:
	bool succeed_;
	bool checked_;
};

というクラスを用意して、処理の成否をこれで表現することにする。

succeed GetSomeValue(int* p) {
	if(!p) return succeed(false);
	*p=100;
	return succeed(true);
}
int main() {
	int n;
	GetSomeValue(&n); //失敗を想定しない場合、エラーチェックする必要はない。

	bool result=GetSomeValue(0);
	if(!result) cout << "エラー" << endl; //if(GetSomeValue(0)) ... でもよい
	
	GetSomeValue(0); //throws unchecked_error exception
}

見られていない戻り値を自動チェックし、エラーがあった場合に例外を投げてくれる。

問題

代入時のコピーコンストラクタ周りの挙動を理解していないため、処理系によってはひどいことになる可能性。
あと実装をよく理解して使わないと死ぬ(実行時に)。