我(快速)查看了 C++ 标准和在线 C++ 参考,但我找不到这个简单问题的答案:
std::list<int>
throw的默认构造函数可以吗?
如果是这样,它为什么会抛出?
我(快速)查看了 C++ 标准和在线 C++ 参考,但我找不到这个简单问题的答案:
std::list<int>
throw的默认构造函数可以吗?
如果是这样,它为什么会抛出?
简短的回答:它可以,但它可以以一种相当安全的方式实现:
默认构造函数构造一个空列表,因此几乎不需要在进程中实际分配内存。大多数列表实现不会为空列表分配任何内存。
然而,默认构造函数并不是真正的默认构造函数,因为它有一个默认参数:explicit list(const Allocator& = Allocator());
Allocator
它本身是一个模板参数,所以如果有一个足够愚蠢(或复杂)的实现提供一个抛出默认构造函数,那么构造函数的调用Allocator
可能已经抛出,即如果默认参数的构造抛出。
如果的默认构造函数Allocator
没有抛出,那么提供一个std::list
默认构造函数也不会抛出的实现是非常容易的。但是库实现者不需要这样做。
更新:必须list
存储给定分配器的副本以便以后能够调用它。与我之前的主张相反,对复制构造函数的调用Allocator
可能不会抛出(第 17.6.3.5 节,见评论)。该list
实现也不允许例如默认构造分配器并在构造函数中进行复制分配,因为这会破坏任何尝试使用list
不可默认构造的分配器的代码。
C++11 标准将list
的默认构造函数声明为
explicit list(const Allocator& = Allocator());
, 其中不包括noexcept
. 因此,标准隐含地允许它抛出异常。
它可能会通过分配空间new
来创建其内部结构,所以是的,它可能会抛出。