From 3999515605481792952
X-Google-Thread: f78e5,adf0c498ff865076,start
X-Google-Attributes: gidf78e5,public
X-Google-Language: ENGLISH,ASCII-7-bit
Path: g2news2.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local02.nntp.dca.giganews.com!nntp.speakeasy.net!news.speakeasy.net.POSTED!not-for-mail
NNTP-Posting-Date: Fri, 21 Jul 2006 02:10:01 -0500
Return-Path: <devnull@stump.algebra.com>
X-Authentication-Warning: mulga.csse.unimelb.edu.au: fjh set sender to devnull@stump.algebra.com using -f
X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov)
X-Original-To: std-c++@mailman.ucar.edu
Delivered-To: std-c++@mailman.ucar.edu
From: "Oleg" <beholder@gorodok.net>
Newsgroups: comp.std.c++
Subject: Exception handling. Extension request
Organization: http://groups.google.com
Message-ID: <1153464622.485595.254900@i42g2000cwa.googlegroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
X-Complaints-To: groups-abuse@google.com
User-Agent: G2/0.2
X-HTTP-UserAgent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4,gzip(gfe),gzip(gfe)
X-HTTP-Via: 1.1 academ.org:7777 (squid/2.5.STABLE9)
Complaints-To: groups-abuse@google.com
Injection-Info: i42g2000cwa.googlegroups.com; posting-host=81.222.113.153;
   posting-account=TxfnwQ0AAABWD8cPztY8NZeutFlPwa7C
X-Virus-Scanned: amavisd-new at ucar.edu
X-Virus-Scanned: amavisd-new at csse.unimelb.edu.au
Approved: Fergus Henderson <fjh@cs.mu.oz.au>, moderator of comp.std.c++
X-Virus-Scanned: amavisd-new at csse.unimelb.edu.au
Date: Fri, 21 Jul 2006 02:09:46 CST
Lines: 187
NNTP-Posting-Host: 65.182.171.162
X-Trace: sv3-DgYkhMDwnKeC9DOe8q1unU43QpHG4ylQQ9r+Mz5XZ89UrFMtZw7hPF1w2HSKeGvZoNCnWjcDGcMyvJK!PDy5fj05gCEPC2UXkJo9Lun6j+ca2TMni7S/7Ry0J2AvRtXiT6F2bIZEPZB6clJWcX8LCAYEw0EE!89yGL7+wS/bhNlylNijnZU2A2DX8ResKyKhXs1wPHZw=
X-Complaints-To: abuse@speakeasy.net
X-DMCA-Complaints-To: abuse@speakeasy.net
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.32
Xref: g2news2.google.com comp.std.c++:2928

Hello!

In current C++ language exception handling is defined with well
structured exception hierarchies in mind. In this case exception
handling is simple: catch(base_exception& e) and be happy.

Problem arises when one have to handle many unrelated exceptions
that does not correspond to single hierarchy or even in a not so rare
case where one needs to provide different responses for different
exceptions in the same hierarchy.


The first is common on subsystem boundaries like C++ - C or C++ - GUI
event handlers. The second is common in system-level errors handling
as it is in boost::filesystem library.

There are workarounds exists that are based on "throw in catch(...)"
idiom:

try {
//...
} catch(...) {
handle_exceptions();
}

void handle_exceptions() {
  assert(std::uncaught_exception());
  try {
    throw;
  } catch (exception_type1& e) {
    //handle it
  } catch (exception_type2& e) {
    //handle it
  } catch (exception_type3& e) {
    //handle it
  }
  // etc.
}


But I believe that the problem mentioned can be elegantly solved on
a language level. All we need is just allowing the following:

class A {};
class B {
public :
   B(A const& a);
};

void foo()
try {
   throw A;
} catch (B b) {
   //caught
}


The idea behind it is simple: if A was thrown and B can be constructed
from it then the catch(B b) handler is called.

With this extension one can do the following:

typedef boost::variant< int, std::string > my_exception;
class my_exception_visitor
     : public boost::static_visitor<>
{
public:

     void operator()(int & i) const
     {
         //...
     }

     void operator()(std::string & str) const
     {
         //...
     }

};

void foo()
try {
   if(...) throw 1;
   else throw std::string("Hello world!");
} catch (my_exception e) {
   boost::apply_visitor( my_exception_visitor(), e );
}


In order to use polymorphic exceptions one can do:

#include <iostream>
#include <boost/variant.hpp>

class base {
public :
    virtual void print() const {
        std::cout << "base\n";
    }
};
class child :
    public base {
public :
    void print() const {
        std::cout << "child\n";
    }
};

class my_visitor :
    public boost::static_visitor<>
{
public:
    void operator()(base& b) const
    {
        std::cout << "visit base\n";
        b.print();
    }
    // it is not called
    void operator()(child& c) const
    {
        std::cout << "visit child\n";
        c.print();
    }

    void operator()(int i) const
    {
        std::cout << "int\n";
    }
};

#include <boost/ref.hpp>

int main()
{
    child c;

    typedef boost::variant<boost::reference_wrapper<base>, int> var_t;


    // boost::reference_wrapper should be patched to allow the next
line to compile
    // the following constructor should be added to the
boost::reference_wrapper
class:
    // template<typename T1>
    // reference_wrapper(reference_wrapper<T1> const& rw):
t_(rw.get_pointer()) {}

    var_t v = boost::ref(c);

    boost::apply_visitor( my_visitor(), v );
    // prints:
    // visit base
    // child

    base b;
    v = boost::ref(b);
    boost::apply_visitor( my_visitor(), v );
    // prints:
    // visit base
    // base

    std::cin.get();
    return 0;
}


For boost::filesystem library it means that its clients can use uniform
"exception handling" even without exceptions at all. Versions of
functions with error_code could be replaced with templates that can
accept any visitor instead of error_code. It would be a high-level,
type-safe, reusable and maintainable way to handle system-level
errors in this particular case and in common case where
catch(base_exception&) is not enough.

This post is a call for comments/opinions/improvements of the
basic idea presented.

Best,
Oleg Abrosimov.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]



