Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对于不同类型的T,sizeof(标准::列表<;T>;)是否会有所不同?_C++_Stl - Fatal编程技术网

C++ 对于不同类型的T,sizeof(标准::列表<;T>;)是否会有所不同?

C++ 对于不同类型的T,sizeof(标准::列表<;T>;)是否会有所不同?,c++,stl,C++,Stl,我可以假设对于任何类型T,类型std::list将具有相同的常量大小吗?我只是想说清楚,我指的是“main”类型本身的大小,而不是它分配的内存大小 在我看来,合理的假设是T本身的大小应该只影响使用分配器分配的列表节点的大小 但是,有两件事可能会导致sizeof(std::list)的差异: LI>标准C++库,试图通过将一些 t>代码>实例放入 STD::列表本身,试图优化 STD::列表< /C> >类型。对我来说,这似乎是个坏主意,它可能会打破标准提出的“固定时间”要求 标准的C++,具有

我可以假设对于任何类型
T
,类型
std::list
将具有相同的常量大小吗?我只是想说清楚,我指的是“main”类型本身的大小,而不是它分配的内存大小

在我看来,合理的假设是
T
本身的大小应该只影响使用分配器分配的列表节点的大小

但是,有两件事可能会导致
sizeof(std::list)
的差异:

<> LI>标准C++库,试图通过将一些<代码> t>代码>实例放入<代码> STD::列表本身,试图优化<代码> STD::列表< /C> >类型。对我来说,这似乎是个坏主意,它可能会打破标准提出的“固定时间”要求 标准的C++,具有库代码的专门化:代码> STD::对于一些类型,具有不同大小的专业:列表< /代码>。 我想不出(1)或(2)有什么用处,但我可能错了

我想实现的是使用
std::list
内部为模板类使用固定大小的片分配器



注意:这是关于不同类型的
T
的差异,而不是不同的分配器的差异。我将对所有实例化进行显式控制,它们都将使用
std::allocator

C++11标准(容器)第23章没有说明它们的大小,因此从技术上讲,您不能假设大小是恒定的。实现者可以(理论上)以影响其足迹的方式专门化特定原语的某个容器


实际上,您可以使用
sizeof(list)==sizeof(list)
的静态断言,并使用
sizeof(list)
作为“固定”大小。可能发生的最糟糕的事情是编译时错误。

是的,它可以

据我所知,该标准对
列表
对象的大小没有任何精确保证。不过,还有其他保证


让我们揭穿一些事情:

一个标准的C++库,试图通过将一些<>代码> t>代码>实例放入<<代码> STD::列表本身,试图优化<代码> STD::列表< /代码>类型。对我来说,这似乎是个坏主意,它可能会打破标准提出的“固定时间”要求

它不会以任何方式打破“恒定时间”要求,只要这个数字是有界的,因为O(5)是O(1)。但是,在
拼接
操作期间,节点应该从一个列表移动到另一个列表,而不在内存中移动。因此,禁止本地存储

一个标准的C++,具有库代码的专业性:代码> STD::对于某些类型,具有不同大小的专业:列表< /C>。 由于我们已经排除了本地存储的可能性,很难想象基

std::list
类型本身会有任何其他变化


让我们担心什么是重要的:

std::list
分配的内存由其第二个模板参数:分配器提供。大多数分配器(包括默认的
std::allocator
)使用简单的指针类型:
T*
。。。不过,分配器可以随意更改此类型

因此,通过更改
allocator
参数(更准确地说,是它的指针类型),在我所看到的所有实现中,人们自然会更改
std::list
容器的大小


注意,分配器本身可以专门用于某些类型,然而,使用重新绑定的魔法,实现起来有点困难。

使用
std::list
的类的固定大小片分配器没有什么意义,除非您也为列表本身使用固定大小片分配器,否则列表项的分配可能会比列表头的分配多得多

现在,您当然可以使用列表的第二个模板参数分配器为列表提供自己的固定大小的片分配器。然而,有一个转折点:你不知道这个切片应该有多大。
列表
接受
分配器
,但它真正需要的是
分配器
,其中U是一个包含上一个/下一个指针和T的结构。为了得到它,它调用方法
重新绑定
,该方法具有签名
模板分配器::重新绑定()


因为我实际上需要做一次,所以我所做的是创建一个对象,该对象包含多个片大小的分配器集合。分配器本身拥有一个指向此的共享指针,以及一个指向分配器的共享指针,以表示其参数的大小。在重新绑定时,我从集合中提取了适当的分配器,或者创建了一个分配器(如果它不存在的话)。若您这样做,它将作为一个副作用解决列表的分配问题,因为若有多个大小,它将为每个大小创建单独的池。而且也不会有很多不同的尺寸,因为物体不会很大。

有趣,+1。我很确定,标准并不能保证相同的大小,但仍然是+1,只是一个注释:)我想到了
向量
而不是
列表
,但它可能包含
T*
,并且不是所有的指针都是相同大小的。。。好的,我不完全确定如何创建成员函数的容器,但是…@BoBTFish-所有指针的大小都相同。@KirilKirov:不,那不是真的。@KirilKirov:所需的
char*
大于
int*
,因为它需要对字地址和36位字内的字节偏移量进行编码。这是将字节寻址添加到以前只支持字寻址的体系结构中的结果。+1用于专门考虑分配器如何影响封装外形。非常好。列表在片分配器内部使用,因此必须直接分配。然而,化学需氧量