哪些操作不能在C++;? 今天我知道,在C++中,代码 >不允许抛出异常。

哪些操作不能在C++;? 今天我知道,在C++中,代码 >不允许抛出异常。,c++,exception,C++,Exception,我还知道,以下情况也不能引发异常: 析构函数 读/写基本类型 还有其他的吗? 或者,是否有某种列表列出了可能不会抛出的所有内容? (显然,这比标准本身更简洁。)不能和不应该之间有很大的区别。基元类型上的操作不能抛出,因为许多函数和成员函数,包括标准库和/或许多其他库中的许多操作 现在,在不应该的情况下,可以包括析构函数和交换。根据您实现它们的方式,它们实际上可以抛出,但您应该避免让析构函数抛出,在交换的情况下,提供无抛出保证的交换操作是在类中实现强异常保证的最简单方法,因为您可以将复制放在一

我还知道,以下情况也不能引发异常:

  • 析构函数
  • 读/写基本类型
还有其他的吗?
或者,是否有某种列表列出了可能不会抛出的所有内容?

(显然,这比标准本身更简洁。)

不能和不应该之间有很大的区别。基元类型上的操作不能抛出,因为许多函数和成员函数,包括标准库和/或许多其他库中的许多操作

现在,在不应该的情况下,可以包括析构函数和交换。根据您实现它们的方式,它们实际上可以抛出,但您应该避免让析构函数抛出,在
交换
的情况下,提供无抛出保证的交换操作是在类中实现强异常保证的最简单方法,因为您可以将复制放在一边,在副本上执行操作,然后和原稿交换

但请注意,该语言允许析构函数和
交换
抛出<代码>交换可以抛出,在最简单的情况下,如果不重载它,那么
std::swap
执行一个复制构造、一个赋值和一个销毁,这三个操作都可以抛出一个异常(取决于您的类型)

在C++11中,析构函数的规则已经改变,这意味着没有异常的析构函数规范有一个隐式的
noexcept
规范,这反过来意味着如果它抛出异常,运行时将调用
terminate
,但您可以将异常规范更改为
noexcept(false)
然后析构函数也可以抛出


最终,如果不了解代码库,就无法提供异常保证,因为几乎每个C++中的函数都允许被抛出。

,这并不能完全回答你的问题——我从自己的好奇心中搜索了一点-但是我相信有保证的函数/操作符大多源于C++中的任何C样式函数,以及一些简单到足以简单的函数。作出这样的保证。一般来说,C++程序不希望提供这种保证(),甚至不清楚这样的保证是否能为经常使用异常的代码提供有用的信息。我找不到一个完整的所有C++函数的列表,这些函数是抛出函数(如果我错过了一个标准的命令,请纠正我),而不是交换、析构函数和原始操作的列表。此外,对于库中未完全定义的函数,要求用户实现nothrows函数的情况似乎相当罕见

所以,为了找到问题的根源,你应该假设任何东西都可以抛入C++,当你发现绝对不能抛出异常的东西时,把它当作一个简化。编写异常安全的代码与编写无bug的代码非常相似——这比听起来更难,老实说,这往往不值得付出努力。此外,异常不安全代码和强nothrow函数之间有许多级别。请参阅以下关于编写异常安全代码作为以下几点的验证的精彩答案:。在boost站点有更多关于异常安全的信息

对于代码开发,我从教授和编码专家那里听到了关于什么应该和不应该抛出异常以及这些代码应该提供什么保证的不同意见。但是一个相当一致的断言是,代码可以很容易地抛出异常,应该非常清楚地记录,或者指示函数定义中的抛出能力(不总是单独适用于C++)。可能引发异常的函数比从不引发异常的函数更为常见,了解可能发生的异常非常重要。但是,保证将一个输入除以另一个输入的函数永远不会抛出除法0异常可能是非常不必要/不需要的。因此,nothrow可以让人放心,但对于安全的代码执行来说,它不是必需的或总是有用的

回复对原始问题的评论:

人们有时会说,在抛出容器或一般情况下,异常抛出构造函数是有害的,应该始终使用两步初始化和is_有效检查。然而,如果一个构造函数失败了,它通常是不可修复的,或者处于一个唯一的坏状态,否则这个构造函数会首先解决这个问题。检查对象是否有效就像在初始化代码周围放置try-catch块一样困难,因为您知道对象很可能引发异常。那么哪一个是正确的呢?通常,在代码库的其余部分中使用的是哪个,或者您个人的偏好。我更喜欢基于异常的代码,因为它给我一种更灵活的感觉,而不需要检查每个对象的有效性(其他人可能不同意)

这给您留下了什么原始问题和评论中列出的扩展?嗯,从提供的来源和我自己的经验,担心在NoCurvin函数的“异常安全”的观点,C++往往是错误的方法来处理代码开发。相反,请记住您知道的函数可能会合理地抛出异常,并适当地处理这些情况。这通常涉及IO操作,您无法完全控制触发异常的内容。如果您得到了一个您从未预料到或认为不可能的异常,那么您的逻辑(或您对函数使用的假设)中有一个bug,您需要修复源代码以适应。试图对非平凡的代码做出保证(有时甚至如此)