C ++标准列表和默认constructible类型
-
22-08-2019 - |
题
这是为什么std::list<T>
的单个参数的构造需要T
是一个缺省constructible类型?我指的是下面的代码不会编译。
struct Foo { // does not have default constructor.
Foo (int i) {}
}
int main(void) {
std::list<Foo> l(10);
}
看来可能使用构造和破坏成语如他们在的std ::向量已经做了,尽管有更多的记账清单类。
在一个相关的说明,为什么没有在列表中的容量功能?你可以争辩说,这样的功能将支付内存分配成本的前期和消除以后,你push_back
对象的开销。至少它将使2个STL序列容器的接口略微更加一致。
解决方案
的std ::列表不具有容量函数,因为它是没有意义的;它从来没有来调整像一个矢量一样。它的容量只受可用的存储器,这是不容易确定的限制。
这是你问什么,我想你真正想要的储备()。这是一个一次性的载体,因为它(严重)需要这样的东西;还有让所有的功能在所有的STL容器一致没有特别的要求,尤其是当他们为别人没什么意义。
可以实现使用自定义分配器相同的效果。如曼努埃尔建议的,看的推动作用。
其他提示
有是该类型是缺省构造没有一般要求 - 它必须可拷贝和分配。您的代码不工作,因为你尝试创建的10个项目清单 - 他们必须以某种方式构建的,因此必须使用默认的构造函数 - 但只有在这种特殊情况下。如果你创建了一个空列表,并添加到它,就没有这样的要求。
也是如此针对其它容器 - 尝试编译以下内容:
#include <vector>
struct A {
A( int x ) : z(x) {}
int z;
};
std::vector <A> a(10);
关于你的问题的第二部分,我只是观察接口的那个稠度不是素设计准则的标准容器 - 没有意图,例如,一个类型的容器是一个“插入式“更换为另一种。这是一个很好的这在项目1和2斯科特迈尔斯书的讨论‘有效STL’。
另外请注意,您调用resize()方法时,需要一个默认的构造函数。
您可以通过具有指针到对象的STL列表规避这一点,但我想这已经是明显的给你。
在一个相关的说明,为什么不能有 在列表容量的功能?您可以 认为这样的功能将支付 存储器分配成本的前期和 后来消除了开销,因为你 的push_back对象。它至少会 做两个STL的接口 序列容器略多 是一致的。
我想这里的问题是, STL列表允许跨列表剪接一>。如果你想分配内存的前期,有一个看的升压池分配器。
的原因是,当构造n个元素(其中n是在构造中使用的参数)的列表,该列表填充其n个元素的结构与T()的拷贝。
请参阅 SGI STL文档列表。
这是为什么所述单个参数 性病的构造::列表需要ŧ 是一个缺省constructible类型?
由于此构造器 - 创建与元素(数其中传递作为参数的)列表。每个元素的值将被默认。你也可以使用构造函数有两个参数,创建将与第二个元素值初始化的元素列表。
在一个相关的说明,为什么不能有 在列表的容量函数?
它不具有意义,因为添加新的元素列表的成本比在情况下与载体多少。
的std ::载体不具有这样的 限制。我的问题是,为什么不 使用相同的技术 (创建/销毁成语)在 的std ::列表以及?
这不是限制。因为如果你不使用这样的构造函数,默认初始值将不是必需的。同样的事情真正为矢量。
所以你的问题实在是“为什么不能有储备和能力的功能列表中?”
这个问题的答案是没有理由保留存储器提前列表 - 添加新的元素不会需要的realloc&复制现有的元件,有不要求存储保持的列表中的内容是连续的,并且迭代做list::push_back()
时没有得到无效的。
所有这些都是用于vector<>::reserve()
的存在的原因,并在储备新的元素具有存储器就是为什么vector<>
将执行放置new
成原始存储器中。