Exception lib proposal

Boost MLで例外ライブラリが提案されていました。
http://lists.boost.org/Archives/boost/2006/06/106965.php
http://lists.boost.org/Archives/boost/2006/06/106607.php

面白いのは情報の付加の仕方です。普通に考えると、基本となる新しい例外クラスを作る場合、

namespace my
{

// 独自の基底クラス
class exception : public std::exception
{
// ここに独自の仮想関数を追加
};

class foo_exception : public foo_exception
{
// ...
}

class bar_exception : public foo_exception
{
// ...
}

} // End namespace my.

のようにするところですが、このライブラリでは、

namespace boost
{

// 追加の例外情報
class exception_info
{
    // ...
};

// このクラスがミソ
// Tは普通の例外クラス
template<class T>
class unspecified_exception_type
    : public T
    , public exception_info
{
    // ...
};

// 送出用の例外ラッパーを作成する
template<class T>
unspecified_exception_type<T> failed()
{
    return unspecified_exception_type<T>();
}

} // End namespace boost.

のようになっており、多重継承により情報を付加しています。
こうすることで、

class read_error
{
    // ...
};

try
{
    // throw read_error() の代わり
    throw boost::failed<read_error>()
        << boost::wrap_errno(); // 例外に情報を追加できる
}
catch (read_error& e)
{
    // これまで通りの使い方
    std::cerr << e.what() << std::endl;

    // 付加情報があるかどうかチェック
    if (boost::exception_info* p = dynamic_cast<boost::exception_info*>(&e))
    {
        // pからさらに情報を引き出せる
    }
}

といったことが可能になります。

  • 既存の例外クラスを変更する必要がない
  • 既存のcatch節を必ずしも変更する必要がない

点が興味深いです。