我在几个地方读过std :: vector要求它的模板参数是默认的可构造的。今天我只是尝试了我的一个有delete
d默认构造函数的类,令我惊讶的是它似乎工作正常(使用std :: vector的默认构造函数)。这是可移植的行为,还是这是gcc的STL的实现细节,我应该假设向量要求它的模板参数是默认的可构造的吗?
答案 0 :(得分:17)
在C ++ 11中有两个vector<T>
成员需要默认的可构造T
:
explicit vector(size_type n);
void resize(size_type sz);
没有别的。因此,如果您使用这些签名,则需要具有默认的可构造类型,否则您不需要。
答案 1 :(得分:13)
C ++ 03中的要求是存储在容器中的类型为CopyConstructible
和Assignable
(参见§23.1容器要求)。但是,在C ++ 11中,这些要求是放宽的,并且倾向于应用于对容器执行的操作。因此,简单的默认构造没有要求(参见C ++ 11标准中的teble 96,§23.1)。
只要您尝试复制矢量或向其中插入元素,您就会遇到CopyInsertable
,CopyAssignable
,EmplaceConstructible
,MoveInsertable
,{{1等要求
答案 2 :(得分:6)
std::vector
无条件地要求其元素类型是默认可构造的。
std::vector
(C ++ 98,C ++ 03)的原始规范甚至从未试图在内部默认构造其元素。所有新元素始终是从“从外部”(通过调用代码)提供的对象作为参数的复制构造。这意味着每次在向量中需要默认构造的元素时,代码(调用者)的你的方必须默认构造它并将其提供给std::vector
as要复制的“原始”元素。
例如,当您在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的构造函数,而不是由向量在内部创建。
C ++ 11改变了这一点,现在std::vector
有方法在内部执行内部元素的默认构造。这仍然无条件地要求向量元素是可默认构造的。它只是意味着您需要使用默认构造元素来使用那些特定的std::vector
方法。
答案 3 :(得分:4)
嗯,模板在某种意义上是弱类型的。也就是说,在您的代码调用使用它的方法(可能是内部的)之前,将不会检测到缺少的默认构造函数 - 这将产生编译时错误。
但是,除非您没有触及内部使用默认构造函数的方法,否则您将“安全”。但是,我不知道哪个是“安全”子集,我怀疑它没有被标准定义。示例:矢量复制可能使用resize
,而{{1}}可能使用默认构造函数。