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

Posted

技术标签:

【中文标题】误解 std::runtime_error 的 what() 函数【英文标题】:Misunderstanding what() function of std::runtime_error 【发布时间】:2014-02-20 12:27:24 【问题描述】:

我测试了 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

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

【问题讨论】:

我相信你可以缩小问题的范围;这很复杂。 无复制。嘎嘎就像一个致命的钻石问题。让 my_error 也继承我可以看到的 std::exception 毫无意义。 【参考方案1】:

对象切片。 boost::error_info 复制对象。所以第二个例子从std::runtime_exception的基类复制构造std::exception,在这个过程中丢失了消息。

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

【讨论】:

以上是关于误解 std::runtime_error 的 what() 函数的主要内容,如果未能解决你的问题,请参考以下文章

区别:std::runtime_error 与 std::exception()

如何从 std::runtime_error 继承?

带有“std::runtime_error”的 C++0x random_device

为什么std :: runtime_error的c'tor采用对std :: string的常量引用?

与RCPP在Ubuntu Xenial扔的std :: runtime_error当段错误

定义自己的异常类的最佳实践?