std :: vector :: resize()的奇怪行为与gcc 4.7.0 [英] strange behaviour of std::vector::resize() with gcc 4.7.0
问题描述
我仍然对 std :: vector :: resize()
的行为感到困惑。请考虑以下代码(另请参见 std :: vector< type> 的类型要求) p>
I'm still confused about the behaviour of std::vector::resize()
. Consider the following code (see also type requirements for std::vector<type>)
struct A {
A() : X(0) { std::cerr<<" A::A(); this="<<this<<'\n'; }
A(A const&) { assert(0); } // is required but doesn't fire in vector::resize
int X;
};
int main()
{
std::vector<A> a;
a.resize(4); // would not compile without A::A(A const&) or A::A(A&&)
}
没有 A :: A(A const&)
或 A :: A(A&
, a.resize(4);
不会编译。但是,该构造函数不会被调用: assert(0)
不会触发!有人可以向我解释一下吗?
Without A::A(A const&)
or A::A(A&&)
, the line with a.resize(4);
doesn't compile. However, that constructor is never called: the assert(0)
doesn't fire! Can somebody explain that to me?
我的解释是这两个构造函数的存在是 allocator_traits<
(由 std :: vector :: resize()
使用),但实际上从未调用。
My interpretation is that the presence of either of these constructors is required by the template magic of allocator_traits<>
(used by std::vector::resize()
), but is actually never called. However, why would you require the presence of a method if you're not calling it?
推荐答案
标准的最新修订版本( n3376 )说: p>
The latest revision of the standard (n3376) says:
12 - 如果
size()< sz
,
将sz - size()
默认插入的元素添加到序列中。需要:T
应为MoveInsertable
和DefaultInsertable
into* this
。
12 - If
size() < sz
, appendssz - size()
default-inserted elements to the sequence.
13 - Requires:T
shall beMoveInsertable
andDefaultInsertable
into*this
.
这意味着 MoveInsertable
是可能发生的任何重新分配所必需的,而
DefaultInsertable
是实际追加所必需的。因此,只有在您的向量已经包含元素并需要重新分配时,您的复制或移动构造函数才会触发。
The implication is that MoveInsertable
is required for any reallocation that might occur, while DefaultInsertable
is required for the actual appending. So your copy or move constructor will fire only if your vector already contains elements and needs to be reallocated.
确实,如果我们写:
std::vector<A> a;
a.resize(1);
assert(!a.empty() && a.capacity() < 4);
a.resize(4);
然后复制或移动构造函数 A
被调用,并且您的断言被触发。
then the copy- or move-constructor of A
is called, and your assert is triggered.
这篇关于std :: vector :: resize()的奇怪行为与gcc 4.7.0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!