Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
491 views
in Technique[技术] by (71.8m points)

c++ - type requirements for std::vector<type>

I am still confused about the requirements for a type to be used with a std::vector in C++11, but this may be caused by a buggy compiler (gcc 4.7.0). This code:

struct A {
  A() : X(0) { std::cerr<<" A::A(); this="<<this<<'
'; }
  int X;
};

int main()
{
  std::vector<A> a;
  a.resize(4);
}

works fine and produces the expected output, indicating that the default ctor (explicitly given) is called (and not an implicit copy ctor). However, if I add a deleted copy ctor to the class, viz

struct A {
  A() : X(0) { std::cerr<<" A::A(); this="<<this<<'
'; }
  A(A const&) = delete;
  int X;
};

gcc 4.7.0 does not compile, but tries to use the deleted ctor. Is that correct behaviour or a bug? If the former, how to get the code working?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The C++11 standard does indeed require CopyInsertable as others have pointed out. However this is a bug in the C++11 standard. This has since been corrected in N3376 to MoveInsertable and DefaultInsertable.

The vector<T, A>::resize(n) member function requires MoveInsertable and DefaultInsertable. These roughly translate to DefaultConstructible and MoveConstructible when the allocator A uses the default construct definitions.

The following program compiles using clang/libc++:

#include <vector>
#include <iostream>

struct A {
  A() : X(0) { std::cerr<<" A::A(); this="<<this<<'
'; }
  A(A&&) = default;
  int X;
};

int main()
{
  std::vector<A> a;
  a.resize(4);
}

and for me prints out:

 A::A(); this=0x7fcd634000e0
 A::A(); this=0x7fcd634000e4
 A::A(); this=0x7fcd634000e8
 A::A(); this=0x7fcd634000ec

If you remove the move constructor above and replace it with a deleted copy constructor, A is no longer MoveInsertable/MoveConstructible as move construction then attempts to use the deleted copy constructor, as correctly demonstrated in the OP's question.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...