误解了std :: runtime_error的what()函数

时间:2014-02-20 12:27:25

标签: c++ exception boost stl

我测试了 Boost.Exception 库并面临莫名其妙的行为。两个下一个样本的输出不同。

#include <iostream>
#include <boost/exception/all.hpp>

typedef boost::error_info<struct tag_my, std::runtime_error> my_info;
struct my_error : virtual boost::exception, virtual std::exception {};

void foo () { throw std::runtime_error("oops!"); }

int main() {
  try {
    try { foo(); }
    catch (const std::runtime_error &e) {
      throw my_error() << my_info(e);
    }
  }
  catch (const boost::exception& be) {
    if (const std::runtime_error *pe = boost::get_error_info<my_info>(be))
      std::cout << "boost error raised: " << pe->what() << std::endl;
  }
}

//output
//boost error raised: oops!

当我将std::runtime_error更改为std::exception时,我得到了以下内容

#include <iostream>
#include <boost/exception/all.hpp>

typedef boost::error_info<struct tag_my, std::exception> my_info;
struct my_error : virtual boost::exception, virtual std::exception {};

void foo () { throw std::runtime_error("oops!"); }

int main() {
  try {
    try { foo(); }
    catch (const std::exception &e) {
      throw my_error() << my_info(e);
    }
  }
  catch (const boost::exception& be) {
    if (const std::exception *pe = boost::get_error_info<my_info>(be))
      std::cout << "boost error raised: " << pe->what() << std::endl;
  }
}

//output
//boost error raised: std::exception

为什么第二个样本会产生它的输出?

1 个答案:

答案 0 :(得分:1)

对象切片。 boost::error_info制作该对象的副本。因此,第二个示例从std::exception的基类复制构造std::runtime_exception,在此过程中丢失了消息。

std::exception无法存储自定义消息;它的what()实现只返回一个硬编码的字符串。