std::vector 适用于非默认可构造的类



我在几个地方读到std::vector要求它的模板参数是默认可构造的。今天我刚刚用我的一个具有 delete d 默认构造函数的类尝试了它,令我惊讶的是它似乎工作得很好(使用 std::vector 的默认构造函数(。这是可移植行为,还是 gcc STL 的实现细节,我是否应该假设向量要求它的模板参数是默认可构造的?

C++11 中有两个vector<T>成员需要默认的可构造T

explicit vector(size_type n);
void resize(size_type sz);

没有别的了。 因此,如果您使用这些签名,则需要具有默认的可构造类型,否则则不需要。

C++03 中的要求是存储在容器中的类型必须CopyConstructibleAssignable(请参阅 §23.1 容器要求(。但是,在 C++11 中,这些要求是放宽的,并且往往适用于在容器上执行的操作。因此,简单的默认构造没有要求(参见 C++11 标准中的 teble 96, §23.1(。

一旦你尝试复制一个向量,或在其中插入元素,你将满足CopyInsertableCopyAssignableEmplaceConstructibleMoveInsertableMoveAssignable等要求。

std::vector不会

无条件地要求其元素类型是默认构造的。

std::vector的原始规范(C++98,C++03(甚至从未尝试在内部默认构造其元素。所有新元素始终从"从外部"(由调用代码(作为参数提供的对象复制构造。这意味着每次在向量中需要默认构造的元素时,代码的一方(调用方(都必须默认构造它并将其作为要复制的"原始"元素提供给std::vector

例如,当您在 C++98 中执行类似操作时

std::vector<some_type> v(42);
v.resize(64);

它实际上扩展到

std::vector<some_type> v(42, some_type(), allocator_type());
v.resize(64, some_type());

通过默认参数机制。换句话说,默认构造的"原始"元素由调用代码提供给 vector 的构造函数,而不是由 vector 在内部创建。

C++11 更改了这一点,现在std::vector具有在内部执行其元素的默认构造的方法。这仍然不无条件地要求向量元素是默认可构造的。这只是意味着你需要默认可构造的元素来使用这些特定的std::vector方法。

嗯,模板在某些意义上是弱类型的。也就是说,在代码调用使用它的方法(可能是内部(之前,不会检测到缺少的默认构造函数 - 这将给出编译时错误。

但是,除非您没有接触内部使用默认构造函数的方法,否则您是"安全的"。但是,我不知道哪个是"安全"子集,我怀疑它不是由标准定义的。示例:向量复制可能使用 resize ,而 又可能使用默认构造函数。

相关内容

最新更新