我在几个地方读到 std::vector 要求它的模板参数是默认可构造的。今天我刚刚用我的一个具有delete
d 默认构造函数的类进行了尝试,令我惊讶的是,它似乎工作得很好(使用 std::vector 的默认构造函数)。这是可移植的行为,还是 gcc 的 STL 的实现细节,我应该假设 vector 要求它的模板参数是默认可构造的?
4 回答
There are two vector<T>
members that require a default constructible T
in C++11:
explicit vector(size_type n);
void resize(size_type sz);
Nothing else does. So if you use these signatures, you need to have a default constructible type, else you do not.
C++03 中的要求是存储在容器中的类型是CopyConstructible
和Assignable
(参见 §23.1 容器要求)。但是,在 C++11 中,这些要求被放宽了,并且倾向于适用于在容器上执行的操作。因此,一个简单的默认构造没有任何要求(参见 teble 96, §23.1 in C++11 标准)。
只要您尝试复制矢量或向其中插入元素,您将满足CopyInsertable
, CopyAssignable
, EmplaceConstructible
,MoveInsertable
等MoveAssignable
要求
std::vector
不无条件地要求其元素类型是默认可构造的。
(C++98, C++03)的原始规范std::vector
甚至从未尝试在内部默认构造其元素。所有新元素总是从“从外部”(由调用代码)作为参数提供的对象复制构造。这意味着每次您需要向量中的默认构造元素时,您的代码(调用者)必须默认构造它并将其std::vector
作为要复制的“原始”元素提供。
例如,当你在 C++98 中做这样的事情时
std::vector<some_type> v(42);
v.resize(64);
it actually expands into
std::vector<some_type> v(42, some_type(), allocator_type());
v.resize(64, some_type());
through the default argument mechanism. In other words, the default-constructed "original" element is supplied to vector's constructor by the calling code, not created internally by the vector.
C++11 changed that and now std::vector
has methods that perform default construction of its elements internally. This still does not unconditionally require vector elements to be default-constructible. It just means that you need default-constructible elements to use those specific std::vector
's methods.
嗯,模板在某种意义上是弱类型的。也就是说,在您的代码调用使用它的方法之前,可能不会在内部检测到缺少的默认构造函数——这将产生编译时错误。
但是,除非您不接触在内部使用默认构造函数的方法,否则您是“安全的”。但是,我不知道哪个是“安全”子集,并且我怀疑它没有被标准定义。示例:向量复制可能使用resize
,而后者又可能使用默认构造函数。