errorable
というクラスを作りました。エラーになった理由を持てるoptional
です。実装は、boost::variant
のラッパー。Eitherみたいなものです。
#include <iostream> #include <system_error> #include <shand/errorable.hpp> int main() { // 初期状態はエラー { shand::errorable<int> x; BOOST_ASSERT(x.is_error()); } // エラーが発生しているケース // エラー理由を格納する // デフォルトのエラー型はstd::string { shand::errorable<int> value = shand::error("invalid argument"); if (boost::optional<std::string> err = value.get_error()) { std::cout << err.get() << std::endl; } } // 正常な値が入っているケース { shand::errorable<int> value = 3; if (boost::optional<int> x = value.get_value()) { std::cout << x.get() << std::endl; } } // 値が正常かエラーかによって、関数を呼び分ける { shand::errorable<int> value = shand::error("invalid argument"); value.value_if([](int x) { std::cout << x << std::endl; }) .error_if([](const std::string& err) { std::cout << err << std::endl; }); } // 第2テンプレート引数で、エラー型をカスタマイズ可能 { shand::errorable<int, std::errc> value = shand::error(std::errc::invalid_argument); if (boost::optional<std::errc> err = value.get_error()) { std::cout << std::make_error_code(err.get()).message() << std::endl; } } }
invalid argument 3 invalid argument Invalid argument
ソースファイル:
https://github.com/faithandbrave/Shand/blob/master/shand/errorable.hpp
現状の機能:
- 第1テンプレート引数で、正常値の型をとる
- 第2テンプレート引数で、エラー値の型をとる(デフォルトは
std::string
) - エラー値は、
error()
フリー関数を通してerrorable
オブジェクトに代入する。 get_value()
/get_error()
メンバ関数で、正常値もしくはエラー値を取得できる。返されるのはboost::optional
。value_if()
/error_if()
メンバ関数で、正常値もしくはエラー値どちらかの場合のみに呼び出される関数を指定できる。
現状の問題:
errorable
という名前はtypoしやすい。別の名前を検討する。- デフォルトコンストラクトした状態は、「デフォルトのエラー値」となってしまって使いにくい。empty状態を用意すべきか。
value_if()
/error_if()
の戻り値は、現在はvoid
だが、なんとか値を返せないだろうか。