如何施加boost :: exception?

时间:2017-05-29 18:01:02

标签: c++ boost exception-handling

考虑以下示例(取自https://theboostcpplibraries.com/boost.exception

#include <boost/exception/all.hpp>
#include <exception>
#include <new>
#include <string>
#include <algorithm>
#include <limits>
#include <iostream>

typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info;

struct allocation_failed : public std::exception
{
  const char *what() const noexcept { return "allocation failed"; }
};

char *allocate_memory(std::size_t size)
{
  char *c = new (std::nothrow) char[size];
  if (!c)
    BOOST_THROW_EXCEPTION(allocation_failed{});
  return c;
}

char *write_lots_of_zeros()
{
  try
  {
    char *c = allocate_memory(std::numeric_limits<std::size_t>::max());
    std::fill_n(c, std::numeric_limits<std::size_t>::max(), 0);
    return c;
  }
  catch (boost::exception &e)
  {
    e << errmsg_info{"writing lots of zeros failed"};
    throw;
  }
}

int main()
{
  try
  {
    char *c = write_lots_of_zeros();
    delete[] c;
  }
  catch (boost::exception &e)
  {
    std::cerr << *boost::get_error_info<errmsg_info>(e);
  }
}

函数allocate_memory()使用以下语句抛出异常

BOOST_THROW_EXCEPTION(allocation_failed{});

在catch块中如何将boost::exception &e转换回allocation_failed

另外,如果我的代码有多个throw语句,如BOOST_THROW_EXCEPTION(A{})BOOST_THROW_EXCEPTION(B{})BOOST_THROW_EXCEPTION(C{})等,其中A,B,C是类。在不使用boost的情况下,我可以按以下方式为每种类型的异常设置单独的catch块。

...
catch(A e){
...
}
catch(B e){
...
}
catch(C e){
...
}

如何在使用提升时执行相同操作,以便BOOST_THROW_EXCEPTION(A{})BOOST_THROW_EXCEPTION(B{})BOOST_THROW_EXCEPTION(C{})等转到不同的catch块?

我是新手来推动图书馆,其中一些概念让我望而却步。

1 个答案:

答案 0 :(得分:2)

除了继承BOOST_THROW_EXCEPTION之外,

boost::exception总是抛出一个继承其参数类型的类型。这意味着两件事:

  1. 您可以dynamic_castboost::exception到传递的类型。
  2. -

    catch (boost::exception &e)
    {
        std::cerr << *boost::get_error_info<errmsg_info>(e);
        if ( allocation_failed* af = dynamic_cast<allocation_failed*>(&e) )
        {
            std::cerr << af->what() << std::endl; // redundant
        }
    }
    
    1. 您可以直接捕获传递的类型。但是,您应始终通过引用捕获以避免切片。 (这个建议与您是否使用助推等无关。)
    2. -

      catch (A& a) {
          // ...
      } catch (B& b) {
          // ...
      } catch (C& c) {
          // ...
      }
      

      当然,这样做,如果您想要任何提升错误格式或额外数据,则需要dynamic_cast将异常对象boost::exception*