sizeof(std::list<T>) 可以因不同类型的 T 而异吗?
Can sizeof(std::list<T>) vary for different types of T?
我可以假设对于任何类型的T
,类型std::list<T>
都将具有相同的常量大小吗?为了说明清楚,我指的只是"主"类型本身的大小,而不是它分配的内存的大小
在我看来,假设T
本身的大小应该只影响使用分配器分配的列表节点的大小似乎是合乎逻辑的。
然而,有两件事可能会导致sizeof(std::list<T>)
的变异,我可以想到:
- 一个标准C++库,试图通过将一些
T
实例放入std::list<T>
本身来"优化"std::list
类型。对我来说,这似乎是个坏主意,它可能打破了标准提出的"恒定时间"要求 - 一种标准C++,对某些类型具有
std::list<T>
的库专用化,专用化具有不同的大小
我想不出(1)或(2)有什么用,但我可能错了。
我想实现的是为内部使用std::list<T>
的模板类使用一个固定大小的切片分配器。
注意:这是关于不同类型的T
的差异,而对于不同的分配器,不是。我将对所有实例化进行显式控制,并且它们都将使用std::allocator
。
是,可以。
据我所知,该标准并不能精确保证list<T>
对象的大小。不过,还有其他保证。
让我们揭穿一些事情:
一个标准C++库,试图通过将一些
T
实例放入std::list<T>
本身来"优化"std::list
类型。对我来说,这似乎是个坏主意,它可能打破了标准提出的"恒定时间"要求;
它不会以任何方式打破"恒定时间"的要求,只要这个数字是有界的,因为O(5)是O(1)。但是,在splice
操作期间,节点应该从一个列表移动到另一个,而不在内存中移动。因此,禁止本地存储。
一种标准C++,对某些类型具有
std::list<T>
的库专用化,专用化具有不同的大小。
由于我们已经排除了本地存储的可能性,因此很难想象基础std::list<T>
类型本身有任何其他变体。
让我们担心什么是重要的:
std::list<T>
分配的内存由其第二个模板参数提供:分配器。大多数分配器(包括默认的std::allocator<T>
)使用一个简单的指针类型:T*
。。。但是,分配器应该可以随意更改这种类型。
因此,通过更改allocator
参数(更确切地说,是其指针类型),在我所见过的所有实现中,人们自然会更改std::list
容器的大小
请注意,分配器本身可以专门用于某些类型,但使用rebind魔术会更难实现
C++11标准(Containers)的第23章没有说明它们的大小,因此从技术上讲,您不能假设大小是恒定的。实现者可以(理论上)以影响其占用空间的方式为特定原语专门化某个容器。
在实践中,您可以使用静态断言sizeof(list<T>) == sizeof(list<int>)
,并使用sizeof(list<int>)
作为"固定"大小。可能发生的最糟糕的事情是编译时错误。
使用std::list<T>
的类的固定大小切片分配器没有什么意义,除非您也为列表本身使用固定大小的切片分配器,否则列表项的分配可能比列表头的分配多得多。
现在,您当然可以使用列表的第二个模板参数分配器为列表提供自己的固定大小切片分配器。然而,有一个转折点:你不知道切片应该有多大。list<T>
接受allocator<T>
,但它真正需要的是allocator<U>
,其中U是一个包含上一个/下一个指针和t的结构。为了得到它,它调用了具有签名template <typename T> template <typename T> allocator<U> allocator<T>::rebind<U>()
的方法rebind
。
由于我实际上需要做一次,所以我所做的就是创建一个对象,该对象包含多个切片大小的分配器集合。分配器本身拥有一个指向此的共享指针和一个指向分配器的共享指针,以确定其参数的大小。在重新绑定时,我从集合中提取了适当的分配器,或者在不存在分配器的情况下创建一个分配器。如果您这样做,它将作为副作用解决列表的分配,因为如果有多个大小,它将为每个创建单独的池。而且不会有很多不同的尺寸,因为物体不会很大。
- 我收到同义重复编译器错误。我应该如何修复"类型"X"的参数与类型"X"的参数不兼容?
- 为什么我不能在同一行中定义两个相同类型的类的成员指针
- std::list 模板是否需要其实例类型中的复制构造函数(或等效项)?
- CRTP 模式 但是在数据结构中存储非同构类型
- C++类模板类型 std::list
- 获取迭代器在基类型 "intrusive doubly linked list" 的指针字典中的位置
- C++ - 错误:'list'没有命名类型(将对象列为类中的成员变量)
- 'list::list'命名构造函数,而不是类型
- 为什么std::list可以有一个T类型的分配器
- 私有结构(在类中定义)不能用作属于同一类的函数的返回类型吗
- 在std::list中就地创建自定义类型对象
- QPlainTextEdit dragEnterEvent 不接受 text/uri-list mime 类型
- 错误:"模板<类_Tp、类_Alloc>类 std::list"的模板参数列表中参数 1 的类型/值不匹配
- sizeof(std::list<T>) 可以因不同类型的 T 而异吗?
- 您将如何为 std::list<std::string> 创建一个类型映射,以在<String> List in C++ 中为 Java 在 SWIG 中创建?
- 我读过std::list很糟糕。有人可以将其与.网的名单<>类型?我从 C 来到C++#
- 如何编写一个C++函数,根据处理返回不同类型的std::list
- C++ 管理多个同质数据类型
- 无法将 List 中的类型 'uint' 隐式转换为'T'(从类模板)
- list pushback一个包含字符串类型核心的结构