nested_exception のサンプル

例えば自前の XML 読み込みクラスみたいな複雑な作る場合なんかはいろんな(out of range とか null reference、他にも exception を継承していない例外とか、他社ベンダのライブラリを使うならそれが提供している例外とか)例外が出る可能性があるので、それを一つの例外にしてしまいたいときに便利。

class xml_exception : public exception
{
private:
    const char* what_;
    const xml_location location_;

public:
    xml_exception(const char* what, xml_location location) : what_(what), location_(move(location)) { }
    virtual const char* what() const throw() { return what_; }
    const xml_location& location() const { return location_; }
};
class xml_reader
{
private:
    ifstream is_;
    xml_location readLocation_;

public:
    xml_reader(ifstream is) : is_(move(is)) { }
    void read()
    {
        try
        {
            // いろいろな処理
            ...
        }
        catch (...)
        {
            // XML の読み込んでいた位置を教える
            throw_with_nested(xml_exception("例外出たよ!", this->readLocation_));
        }
    }
};
xml_reader reader(ifstream("hoge.xml"));
try
{
    reader.read();
}
catch (xml_exception& e)
{
    // ここで例外が出たときの共通処理
    cout << e.what() << ": " << e.location() << endl;

    // 各例外毎に処理したい場合(あまり無いような気も?)
    try
    {
        throw_if_nested(e);
    }
    catch (bad_alloc& ex) { ... }
    catch (vender_specified_exception& ex) { ... }
    catch (int& ex) { ... }
    catch (...) { ... }
}