c++ - std::vector<type> 的类型要求

标签 c++ constructor c++11 allocation stdvector

我仍然对在 C++11 中与 std::vector 一起使用的类型的要求感到困惑,但这可能是由错误的编译器 (gcc 4.7.0) 引起的.这段代码:

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

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

工作正常并产生预期的输出,表明调用了默认构造函数(明确给出)(而不是隐式复制构造函数)。但是,如果我向类中添加一个已删除的复制构造函数,即

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

gcc 4.7.0 不编译,但尝试使用已删除的构造函数。这是正确的行为还是错误?如果是前者,如何让代码工作?

最佳答案

C++11 标准确实需要 CopyInsertable正如其他人指出的那样。然而,这是 C++11 标准中的一个错误。这已在 N3376 中得到纠正至 MoveInsertableDefaultInsertable .

vector<T, A>::resize(n)成员函数需要 MoveInsertableDefaultInsertable .这些大致翻译为DefaultConstructibleMoveConstructible当分配器 A使用默认 construct定义。

以下程序使用 clang/libc++ 编译:

#include <vector>
#include <iostream>

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

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

对我来说打印出来:

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

如果删除上面的移动构造函数并将其替换为已删除的复制构造函数,A不再是 MoveInsertable/MoveConstructible作为移动构造然后尝试使用已删除的复制构造函数,如 OP 的问题中正确演示的那样。

关于c++ - std::vector<type> 的类型要求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12251368/

相关文章:

c++ - 具有通用引用的成员函数模板不接受左值

c++ - BOOST_SPIRIT_DEFINE 不明白

C++11 GCC 4.6.2 std::move

c++ - 在 C++ 中的无序映射中访问列表的元素

c++ - FFmpeg h265 编码->解码,C++

c# - App构造函数和app.Onstartup有什么区别?

javascript - 我应该使用构造函数/原型(prototype)吗?

c++ - 如何在没有 deadline_timer boost 的情况下将 boost::asio 代码完全转换为 C++11/asio?

c++ - 如果返回类型是 C++ 中的对象,我们可以在函数定义中使用绝对命名空间吗?

c++ - 无法在c++中使用参数从派生类调用基类构造函数