std :: vector :: resize()的奇怪行为与gcc 4.7.0 [英] strange behaviour of std::vector::resize() with gcc 4.7.0

查看:128
本文介绍了std :: vector :: resize()的奇怪行为与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, appends sz - size() default-inserted elements to the sequence.
13 - Requires: T shall be MoveInsertable and DefaultInsertable 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆