我在几个地方读过 std::vector 要求它的模板参数是默认可构造的。今天我只是用我的一个类尝试了它,它有一个delete
d 默认构造函数,令我惊讶的是它似乎工作得很好(使用 std::vector 的默认构造函数)。这是可移植的行为,还是这是 gcc 的 STL 的实现细节,我应该假设 vector 要求它的模板参数
在 C++ 11 中有两个vector<T>
成员需要一个默认的可构造T
:
explicit vector(size_type n);
void resize(size_type sz);
所以如果你使用这些签名,你需要有一个默认的可构造类型,否则你没有。
C ++ 03 中的要求是存储在容器中的类型为CopyConstructible
和Assignable
(请参见 § 23.1 容器要求)。但是,在 C ++ 11 中,这些要求是宽松的,并且倾向于应用于在容器上执行的操作。因此,简单的默认构造没有要求(请参见 teble 96,C ++ 11 标准中的 § 23.1)。
只要您尝试复制一个向量,或将元素插入其中,您就会满足CopyInsertable
,CopyAssignable
,EmplaceConstructible
,MoveInsertable
,MoveAssignable
等要求
std::vector
不会无条件地要求其元素类型是可默认构造的。
std::vector
(C++ 98,C++ 03) 的原始规范甚至从未尝试在内部默认构造其元素。所有新元素总是从“从外部”(由调用代码) 作为参数提供的对象复制构造的。这意味着每次您需要在向量中复制默认构造的元素时,它都是您的代码的端(它的默认构造)
例如,当你在 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
,这反过来可能使用默认构造函数。
本站系公益性非盈利分享网址,本文来自用户投稿,不代表边看边学立场,如若转载,请注明出处
评论列表(50条)