为什么 c++ 中的分配器需要复制构造函数吗?
这里说这是因为异常规范。我不明白。这个问题和异常规范有什么关系吗?
It is said here that it's because of exception specification. I do not understand it. Does this question have any relationship with exception specification?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
读完教程后,我对其中的措辞感到有点困惑。但我相信事情就这么简单:本教程解释了为什么分配器的模板标头显示
allocator(const allocator&) throw();
和
template; allocator(const allocator&) throw();
即使复制构造函数对于分配器来说相当无用。答案是分配器的规范不允许构造函数抛出异常。因此,复制构造函数公共接口定义了带有异常规范的复制构造函数(不抛出任何异常),以防止有人使用可能抛出异常的复制构造函数派生自己的分配器。
请参阅 此链接 详细描述了异常规范是什么(如果这就是抛出您的问题)。 (没有双关语。真的。)
所以,他们并不意味着在创建分配器时,您必须提供复制构造函数。他们只是指出该规范明确禁止您定义引发任何异常的规范。
`
After reading through the tutorial I was a little confused myself by the wording. But I believe it's as simple as this: the tutorial was explaining why the allocator's template header shows
allocator(const allocator&) throw();
and
template <class U> allocator(const allocator<U>&) throw();
even though the copy constructor is fairly useless for an allocator. And the answer was that the specification of an allocator does not allow the constructor to throw exceptions. Therefore the copy constructor public interface defines copy constructors with an exception specification of
throw()
(does not throw any exceptions) to prevent someone deriving their own allocator with copy constructors which might throw an exception.See this link for a good description of what an exception specification is if that's what was throwing you. (No pun intended. Really.)
So, they didn't mean that when creating an allocator, you have to provide a copy constructor. They just were pointing out that the specification specifically prohibits you from defining one that throws any exceptions.
`
您必须显式编写复制构造函数(而不是使用默认值),因为 C++03 分配器的复制构造函数需要使用异常说明符
throw()
进行定义。默认的复制构造函数没有此说明符。从技术上讲,您不必这样做,但如果它确实抛出异常......那么,祝您好运。
但这只是一个小烦恼,因为 C++03 中的分配器不能拥有状态。所以你不应该到处复制成员。复制构造函数可以为空。
You have to explicitly write a copy constructor (rather than use the default) because the copy constructor for a C++03 allocator is required to be defined with the exception specifier
throw()
. The default copy constructor does not have this specifier.Technically, you don't have to, but if it does throw an exception... well, good luck with that.
But that's just a minor annoyance, since allocators in C++03 cannot have state. So you shouldn't be copying members around. The copy constructor can be empty.
分配器需要一个复制构造函数,因为容器有一个复制构造函数,并且需要在此过程中复制其分配器。
The allocator requires a copy constructor because containers have a copy constructor and will need to copy their allocator in the process.
其实很简单。使用分配器的容器的构造函数获取分配器并存储它的副本。为了做到这一点,它需要分配器是
CopyConstructible
。就这样。请注意,除非分配器类型的propagate_on_container_copy_assignment
特征为 true(这种情况很少见),否则分配器类型不需要CopyAssignable
。C++11 规范还规定“这些类型上的构造函数、比较运算符、复制操作、移动操作或交换操作不得通过异常退出”。异常规则允许您创建分配器的(堆栈)副本(尤其是在构造或销毁期间),而不必担心复制分配器会抛出异常。在存在可能引发复制、移动、交换或比较的分配器的情况下设计异常安全的容器几乎是不可能的。在实践中,分配器只能容纳指向某些资源的指针,因此允许分配器进行复制等操作会增加很多痛苦,而几乎没有任何好处。
It's actually pretty simple. The constructor of a container using an allocator takes the allocator and stores a copy of it. In order to do that, it needs the allocator to be
CopyConstructible
. That's all. Note that an allocator type not required toCopyAssignable
unless itspropagate_on_container_copy_assignment
trait is true (which is rare).The C++11 specification also states that "No constructor, comparison operator, copy operation, move operation, or swap operation on these types shall exit via an exception." The exception rules allow you to make a (stack) copy of an allocator (especially during construction or destruction) without worrying that copying the allocator will throw. Designing containers that are exception-safe in the presence of allocators that might throw on copy, move, swap, or compare is nearly impossible. In practice, an allocator cannot hold much more than a pointer to some resource, so allowing allocators to throw on copy, etc., would add a lot of pain for virtually no gain.