除了失败的重新分配或构造之外,是否允许 std::vector::push_back 因任何原因抛出?
考虑一下:
std::vector<int> v;
v.reserve(1);
v.push_back(1); // is this statement guaranteed not to throw?
我选择了 int,因为它没有可以抛出异常的构造函数 - 显然,如果 T 的某些复制构造函数抛出异常,那么该异常就会转义 vector
。
这个问题与 insert
和 push_back
一样适用,但它的灵感来自 将“动态分配的对象”push_back 到向量安全吗?,这恰好询问了 push_back.
在 C++03 和 C++0x 标准/FCD 中,vector::insert
的描述表明,如果没有发生重新分配,则插入点之前的迭代器/引用仍然有效。他们没有说如果没有发生重新分配,就不会抛出异常(除非来自 T 的构造函数等)。
标准中是否有其他内容可以保证这一点?
我不希望 push_back
做任何可能在这种情况下抛出的事情。 GNU 实现则不然。问题是标准是否禁止这样做。
作为后续,有人能想到任何实现都会抛出异常的原因吗?我能想到的最好的办法是,如果对 reserve
的调用最终将容量增加到超过 max_size()
的值,则 insert也许可以抛出
length_error
。将容量增加到超过 max_size()
是没有用的,但我没有立即看到任何禁止这样做的东西,或者[编辑:你的分配器可能会阻止你将容量增加到超过 max_size
>,所以这个建议可能不好。]
Consider:
std::vector<int> v;
v.reserve(1);
v.push_back(1); // is this statement guaranteed not to throw?
I've chosen int
because it has no constructors that could throw - obviously if some copy constructor of T throws, then that exception escapes vector<T>::push_back
.
This question applies as much to insert
as push_back
, but it was inspired by Is it safe to push_back 'dynamically allocated object' to vector?, which happens to ask about push_back
.
In the C++03 and C++0x standard/FCD, the descriptions of vector::insert
say that if no reallocation happens, iterators/references before the insertion point remain valid. They don't say that if no reallocation happens, no exception is thrown (unless from constructors etc of T).
Is there anything elsewhere in the standard to guarantee this?
I don't expect push_back
to do anything that could throw in this case. The GNU implementation doesn't. The question is whether the standard forbids it.
As a follow-up, can anyone think of a reason why any implementation would throw? The best I can think of, is that if a call to reserve
ends up increasing the capacity to a value in excess of max_size()
, then insert
perhaps is permitted to throw length_error
when the max size would be exceeded. It would be useless to increase capacity beyond max_size()
, but I don't immediately see anything forbidding that, either [Edit: your allocator would probably stop you increasing capacity beyond max_size
, so this suggestion might be no good.]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
嗯,这取决于您使用的分配器。
除了分配器之外,您唯一可以依赖的是,如果抛出异常,
push_back()
和push_front()
保证为 noop (23.1-10) 。标准绝对不会禁止push_back()
抛出异常。Well, it kind of depends on the allocator you are using.
Apart from the allocator, the only thing you can rely on is that
push_back()
andpush_front()
are guaranteed to be noop if an exception is thrown (23.1-10). The standard definitely doesn't forbid thepush_back()
from throwing exceptions.