从 C++11 中的 std::exception 派生时的异常规范

2024-01-04

我有一个异常类如下:

#include <exception>

struct InvalidPathException : public std::exception
{
   explicit InvalidPathException() {}
   const char* what() const;
};

const char*
InvalidPathException::what() const {
    return "Path is not valid";
}

在 GCC 4.4 下使用 -Wall -std=c++0x 进行编译时

错误:更宽松的抛出说明符 '虚拟常量字符* InvalidPathException::what() const'

错误:覆盖“虚拟常量字符*” std::exception::what() const throw ()'

也很正确,因为我凌驾于一切之上std::exception's what()确实有一个方法throw()异常说明符。但正如人们经常会被告知 http://www.gotw.ca/publications/mill22.htm,我们不应该使用异常说明符。据我了解,他们是在 C++11 中已弃用 http://en.wikipedia.org/wiki/C%2B%2B0x#cite_ref-sutter0310_6-1,但在 GCC 中显然还没有 -std=c++0x。

所以我现在对最好的方法感兴趣。在我正在开发的代码中,我确实关心性能,因此担心经常提到的开销throw(),但实际上这个开销有这么严重吗?我是否正确地认为我只会在以下情况下遭受痛苦what()实际上被调用,只有在抛出这样的异常之后才会被调用(对于从 std::exception 继承的其他方法也同样如此,所有方法都有throw()说明符)?

或者,有没有办法解决 GCC 给出的这个错误?


Empty throw规范很有用,因为它们实际上可以在调用者的站点上启用编译器优化,如维基百科 http://en.wikipedia.org/wiki/Exception_handling#Checked_exceptions知道(我手头没有技术报价)。

出于优化机会的原因,无抛出规格not在即将推出的标准中已弃用,它们只是看起来不像throw ()不再有,但被称为noexcept。嗯,是的,而且它们的工作方式略有不同。

是关于的讨论noexcept它还详细说明了为什么传统的无抛出规范禁止在被调用方站点进行优化。

一般来说,您为每个throw规范,至少使用完全兼容的编译器,而 GCC 在这方面似乎并不总是如此。那些throw必须在运行时检查规范,即使是空规范。这是因为如果引发了不符合规定的异常throw规范,堆栈展开必须在该堆栈框架内进行(因此除了一致性检查之外,您还需要代码),然后std::unexpected必须被调用。另一方面,您可能会为每个人节省时间/空间empty throw规范,因为编译器在调用该函数时可能会做出更多假设。我胆怯地说,只有分析器才能给您明确的答案,即您的特定代码是否受到以下影响或得到改善(empty!) throws规格。

作为解决您的实际问题的方法,以下方法可以吗?

  • 介绍#define NOTHROW throw ()并将其用于您的例外what和其他东西。
  • 当海湾合作委员会实施noexcept, 重新定义NOTHROW.

Update

正如@James McNellis 所说,throw ()将向前兼容。在这种情况下,我建议只使用throw ()除此之外,如果有疑问,请进行配置文件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 C++11 中的 std::exception 派生时的异常规范 的相关文章

  • 从服务器下载图像(cUrl,但接受建议)C++

    我试图通过从服务器 网站 下载图像来设置旋转背景图像 并尝试使用curl 来执行此操作 但是在执行此操作方面取得了0 成功 我的代码的 缩短的 版本如下 我没有收到错误 但是 如何 临时 保存该图像以将其显示为背景 是否有图像 类型变量 或
  • std::map find 在 C++ 中不起作用[重复]

    这个问题在这里已经有答案了 我使用以下几行创建了一个哈希映射和一个迭代器 std map
  • 地图类容器的专用功能

    我想要专门为矢量和地图之类的容器设计一个函数模板 对于向量 我可以像下面那样做 但我不知道如何才能有一个专门版本的函数 该函数仅用于像地图这样的容器 include
  • MVVM:来自 FileOpenPicker 的图像绑定源

    我将 OnActivated 添加到 app xaml cs 中 它可以正常工作 protected async override void OnActivated IActivatedEventArgs args var continua
  • 字符串/分段错误

    Program to calculate trip and plan flights define TRIP 6 define NAMEMAX 40 define DEST 1 include
  • 二叉树和快速排序?

    我有一个家庭作业 内容如下 别生气 担心 我是not请你帮我做作业 编写一个程序 通过使用二分查找的快速排序方法对一组数字进行排序 树 推荐的实现是使用递归算法 这是什么意思 到目前为止 这是我的解释 正如我在下面解释的那样 我认为两者都有
  • 如何在单例类和未命名类之间进行选择?

    我会使用这样的单例 Singleton single Singleton instance single gt do it 我会使用这样的未命名类 single do it 我觉得单例模式除了具有可读的错误消息之外 与未命名的类相比没有任何
  • C++:避免​​在重载中将字符串自动转换为布尔值

    我想创建一组方法 这些方法将根据其类型输出具有特殊格式的值 当我这样做时 到目前为止看起来还不错 static void printValue std ostringstream out int value out lt lt value
  • 我应该使用字节还是int?

    我记得曾在某处读到 即使您只需要字节 使用 Int32 更好 就性能而言 它 据说 仅适用于您不关心存储的情况 这是有效的吗 例如 我需要一个保存一周中某一天的变量 我是吗 int dayOfWeek or byte dayOfWeek E
  • 我想找到 C# 代码中所有后面没有括号的 if 语句。通过正则表达式

    我想找到所有if声明和for后面没有大括号的语句 当你在一个文件中写入一行时if声明您大多不会将其括在大括号中 所以我想找到所有这些if and for声明 请帮忙 就像我想捕捉这个声明 if childNode Name B return
  • 绑定集合的子集

    我有一个ObservableCollection
  • 现代编译器的 C++ 中“memset”功能的状态

    Context 不久前 我偶然发现了 Alexandrescu 在 2001 年发表的 DDJ 文章 http www ddj com cpp 184403799 http www ddj com cpp 184403799 它是关于比较将
  • 如何处理文件名中的空格

    我正在尝试迭代本地目录中的文件 foreach string name in Directory GetFileSystemEntries path FileAttrtibutes att File GetAttributes name 文
  • 括号内声明的对象的范围

    如果我声明一个这样的对象 void main myclass objectA anotherclass true true 0 即 我通过直接调用后者的构造函数来创建一个 objectA 和另一个对象 anotherclass anothe
  • 用 std::generate_n 填充 std::map

    我想填写一个std map using std generate n但无法让它发挥作用 我尝试过的是这样的事情 unsigned number of pairs 5 std map
  • TCP/IP 传输期间套接字数据损坏

    当我通过预连接的 TCP IP 套接字发送数据时 我发现数据已损坏 Example Station1 正在向 Station2 发送数据 我已经在发送之前 在 S1 和接收之后 在 S2 打印了数据 以下是消息 S1 发送的数据是ACKS2
  • C# 中的 mshtml.HTMLDocumentClass

    在 C 中 我设法从 InternetExplorer 对象获取整个 HTMLDocumentClass 导航到某个 URL 然而 在 Visual Studio 2008 的调试模式下 该特定 URL 的 HTMLDocumentClas
  • 使用属性和性能

    我正在优化我的代码 我注意到使用属性 甚至自动属性 对执行时间有深远的影响 请参阅下面的示例 Test public void GetterVsField PropertyTest propertyTest new PropertyTest
  • 为什么在一行中使用这个 C++ 函数两次会导致编译错误?

    我在尝试在 Visual C 2010 中实现智能相等测试宏类型模板函数时遇到了一些麻烦 该函数与VS 中关于模板函数默认参数的错误 https stackoverflow com questions 10343177 why do i g
  • 将二进制长字符串转换为十六进制 C#

    我正在寻找一种将长二进制字符串转换为十六进制字符串的方法 二进制字符串看起来像这样 0110011010010111001001110101011100110100001101101000011001010110001101101011 我

随机推荐