Boost logo

Boost :

From: Joaquín M López Muñoz (joaquinlopezmunoz_at_[hidden])
Date: 2020-06-07 19:19:36


El 07/06/2020 a las 20:00, Emil Dotchevski escribió:
> On Sun, Jun 7, 2020 at 2:02 AM Joaquin M López Muñoz <joaquinlopezmunoz_at_[hidden]> wrote:
> > I still don't get it. What is the difference between:
> >
> > int main()
> > {
> > return boost::leaf::try_handle_some(
> > []()->boost::leaf::result<int>{
> > return 0;
> > },
> > [](boost::leaf::match<int,0>){return 0;},
> > [](boost::leaf::catch_<std::exception>){return 1;},
> > [](const boost::leaf::error_info&){return 2;}
> > ).value();
> > }
>
> One of your handlers uses catch_<>. This means that your try block will execute inside a try scope, and your handlers will execute in a catch scope.
>
> If the try block throws, LEAF will catch the exception and attempt to find a handler. It doesn't have to be a handler that uses catch_<>, the first suitable handler will be called.

How can a non-catch_ handler be suitable when an exception has been thrown?

> If your try block returns a failure without throwing, LEAF will attempt to find a handler also. In this case, the handler that uses catch_<> will not be called, because no exception was thrown.
>

Understood.

> If a suitable handler could not be found, the error is propagated by rethrowing the exception or returning the result<int> returned from the try block, as appropriate.

Understood.

>
> > and
> >
> > int main()
> > {
> > return boost::leaf::try_catch(
> > []()->boost::leaf::result<int>{
> > return 0;
> > },
> > [](boost::leaf::match<int,0>){return 0;},
> > [](boost::leaf::catch_<std::exception>){return 1;},
> > [](const boost::leaf::error_info&){return 2;}
> > ).value();
> > }
>
> With try_catch, your try block always executes in a try scope, and your handlers execute in a catch scope, even if none of them use catch_<>. If an exception is thrown, try_catch will try to find a suitable handler. It does not understand the semantics of the result type.

I see that, indeed, try_catch does not use non-catch_ handlers:

      auto a=try_handle_some(
        []()->result<int>{
          return new_error(0);
        },
        [](match<int,0>){return 1;},
        [](catch_<std::exception>){return 2;},
        [](const error_info&){return 3;}
      );
      if(a)std::cout<<"value: "<<a.value()<<"\n";
      else std::cout<<"error\n";

prints "value: 1", while

      auto a=try_catch{
        []()->result<int>{
          return new_error(0);
        },
        [](match<int,0>){return 1;},
        [](catch_<std::exception>){return 2;},
        [](const error_info&){return 3;}
      );
      if(a)std::cout<<"value: "<<a.value()<<"\n";
      else std::cout<<"error\n";

prints "error". So, what's the point of allowing non-catch_ handlers in try_catch? Also, seems like
try_handle_some provides a superset of the functionality offered by try_catch, right? In which
situations would a user need try_catch because try_handle_some does not fit the bill?

Joaquín M López Muñoz


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk