- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在开发一个类似容器的类,并且我想像使用标准容器一样使用标准分配器基础结构。在网上我找到了很多关于如何单独使用 std::allocator
类,或者如何为标准容器定义自定义分配器的 Material ,但是关于如何一般使用符合标准的分配器非常少见,尤其是在 C++11 的上下文中,从编写自定义分配器的角度来看,事情似乎要容易得多,但从容器的角度来看,事情要复杂得多。
所以我的问题是关于如何以最通用的方式正确使用符合标准的分配器,具体来说:
我对有关 C++11 世界的答案特别感兴趣(它会改变 C++14 中的任何内容吗?)
最佳答案
在下面的所有答案中,我假设您要遵循 C++11 标准定义容器的规则。该标准不要求您以这种方式编写自定义容器。
- First of all, when should I design a custom container in this way? Is there a sensible performance overhead (including missing optimization opportunities) in using the default allocator instead of plain new/delete?
出于性能原因,自定义分配器最常见和最有效的用途之一是让它在堆栈外分配。如果您的自定义容器不能接受这样的分配器,那么您的客户端将无法执行这样的优化。
- Do I have to explicitly call contained objects' destructors?
您必须明确调用 allocator_traits<allocator_type>::destroy(alloc, ptr)
, 而后者将直接调用 value_type
的析构函数,或将调用 destroy
allocator_type
的成员.
- How do I discriminate between stateful and stateless allocators?
我不会打扰。假设分配器是有状态的。
- How to handle stateful allocators?
非常小心地遵循 C++11 中规定的规则。特别是那些在 [container.requirements.general] 中指定的分配器感知容器。规则太多,这里就不一一列举了。不过,我很乐意回答有关任何这些规则的具体问题。但第一步是获取标准的拷贝,并阅读它,至少是容器要求部分。我推荐the latest C++14 working draft为此目的。
- When (if ever) are two instances interchangeable (when can I destroy with one instance the memory allocated with another one)?
如果两个分配器比较相等,那么任何一个都可以释放从另一个分配的指针。拷贝(通过复制构造或复制分配)需要比较相等。
- They have to be copied when the container is copied?
在标准中搜索 propagate_on
和 select_on_container_copy_construction
了解细节。简单的回答是“视情况而定”。
- They can/have to be moved when the container is moved?
必须用于移动构造。移动分配取决于 propagate_on_container_move_assignment
.
- In the container's move constructor and move assignment operator, when can I move the pointer to allocated memory, and when do I have to allocate different memory and move the elements instead?
新的 move 构造的容器应该通过 move 构造 rhs 的分配器来获得它的分配器。这两个分配器需要比较相等。因此,您可以转移所有已分配内存的内存所有权,您的容器对于该指针的有效状态为 nullptr
在右侧。
移动赋值运算符可以说是最复杂的:行为取决于propagate_on_container_move_assignment
以及两个分配器是否比较相等。更完整的描述在我的“分配器备忘单”中。
- Are there issues about exception safety in this context?
是的,吨。 [allocator.requirements] 列出容器可以依赖的分配器要求。这包括哪些操作可以抛出,哪些不能抛出。
您还需要处理分配器的pointer
的可能性。实际上不是 value_type*
. [allocator.requirements] 也是寻找这些细节的地方。
祝你好运。这不是一个初学者项目。如果您有更具体的问题,请将它们发布到 SO。要开始,请直接进入标准。我不知道有关该主题的任何其他权威来源。
这是我为自己制作的一份备忘单,其中描述了分配器的行为以及容器的特殊成员。它是用英文写的,不是标准的eze。如果您发现我的备忘单和 C++14 工作草案之间有任何差异,请相信工作草案。一个已知的差异是我添加了 noexcept
以标准没有的方式规范。
Allocator behavior:
C() noexcept(is_nothrow_default_constructible<allocator_type>::value);
C(const C& c);Gets allocator from
alloc_traits::select_on_container_copy_construction(c)
.C(const C& c, const allocator_type& a);
Gets allocator from
a
.C(C&& c)
noexcept(is_nothrow_move_constructible<allocator_type>::value && ...);Gets allocator from
move(c.get_allocator())
, transfers resources.C(C&& c, const allocator_type& a);
Gets allocator from
a
. Transfers resources ifa == c.get_allocator()
. Move constructs from eachc[i]
ifa != c.get_allocator()
.C& operator=(const C& c);
If
alloc_traits::propagate_on_container_copy_assignment::value
istrue
, copy assigns allocators. In this case, if allocators are not equal prior to assignment, dumps all resources from*this
.C& operator=(C&& c)
noexcept(
allocator_type::propagate_on_container_move_assignment::value &&
is_nothrow_move_assignable<allocator_type>::value);If
alloc_traits::propagate_on_container_move_assignment::value
istrue
, dumps resources, move assigns allocators, and transfers resources fromc
.If
alloc_traits::propagate_on_container_move_assignment::value
isfalse
andget_allocator() == c.get_allocator()
, dumps resources, and transfers resources fromc
.If
alloc_traits::propagate_on_container_move_assignment::value
isfalse
andget_allocator() != c.get_allocator()
, move assigns eachc[i]
.void swap(C& c)
noexcept(!allocator_type::propagate_on_container_swap::value ||
__is_nothrow_swappable<allocator_type>::value);If
alloc_traits::propagate_on_container_swap::value
istrue
, swaps allocators. Regardless, swaps resources. Undefined behavior if the allocators are unequal andpropagate_on_container_swap::value
isfalse
.
关于c++ - 在自定义容器类中使用分配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21221527/
我需要将文本放在 中在一个 Div 中,在另一个 Div 中,在另一个 Div 中。所以这是它的样子: #document Change PIN
奇怪的事情发生了。 我有一个基本的 html 代码。 html,头部, body 。(因为我收到了一些反对票,这里是完整的代码) 这是我的CSS: html { backgroun
我正在尝试将 Assets 中的一组图像加载到 UICollectionview 中存在的 ImageView 中,但每当我运行应用程序时它都会显示错误。而且也没有显示图像。 我在ViewDidLoa
我需要根据带参数的 perl 脚本的输出更改一些环境变量。在 tcsh 中,我可以使用别名命令来评估 perl 脚本的输出。 tcsh: alias setsdk 'eval `/localhome/
我使用 Windows 身份验证创建了一个新的 Blazor(服务器端)应用程序,并使用 IIS Express 运行它。它将显示一条消息“Hello Domain\User!”来自右上方的以下 Ra
这是我的方法 void login(Event event);我想知道 Kotlin 中应该如何 最佳答案 在 Kotlin 中通配符运算符是 * 。它指示编译器它是未知的,但一旦知道,就不会有其他类
看下面的代码 for story in book if story.title.length < 140 - var story
我正在尝试用 C 语言学习字符串处理。我写了一个程序,它存储了一些音乐轨道,并帮助用户检查他/她想到的歌曲是否存在于存储的轨道中。这是通过要求用户输入一串字符来完成的。然后程序使用 strstr()
我正在学习 sscanf 并遇到如下格式字符串: sscanf("%[^:]:%[^*=]%*[*=]%n",a,b,&c); 我理解 %[^:] 部分意味着扫描直到遇到 ':' 并将其分配给 a。:
def char_check(x,y): if (str(x) in y or x.find(y) > -1) or (str(y) in x or y.find(x) > -1):
我有一种情况,我想将文本文件中的现有行包含到一个新 block 中。 line 1 line 2 line in block line 3 line 4 应该变成 line 1 line 2 line
我有一个新项目,我正在尝试设置 Django 调试工具栏。首先,我尝试了快速设置,它只涉及将 'debug_toolbar' 添加到我的已安装应用程序列表中。有了这个,当我转到我的根 URL 时,调试
在 Matlab 中,如果我有一个函数 f,例如签名是 f(a,b,c),我可以创建一个只有一个变量 b 的函数,它将使用固定的 a=a1 和 c=c1 调用 f: g = @(b) f(a1, b,
我不明白为什么 ForEach 中的元素之间有多余的垂直间距在 VStack 里面在 ScrollView 里面使用 GeometryReader 时渲染自定义水平分隔线。 Scrol
我想知道,是否有关于何时使用 session 和 cookie 的指南或最佳实践? 什么应该和什么不应该存储在其中?谢谢! 最佳答案 这些文档很好地了解了 session cookie 的安全问题以及
我在 scipy/numpy 中有一个 Nx3 矩阵,我想用它制作一个 3 维条形图,其中 X 轴和 Y 轴由矩阵的第一列和第二列的值、高度确定每个条形的 是矩阵中的第三列,条形的数量由 N 确定。
假设我用两种不同的方式初始化信号量 sem_init(&randomsem,0,1) sem_init(&randomsem,0,0) 现在, sem_wait(&randomsem) 在这两种情况下
我怀疑该值如何存储在“WORD”中,因为 PStr 包含实际输出。? 既然Pstr中存储的是小写到大写的字母,那么在printf中如何将其给出为“WORD”。有人可以吗?解释一下? #include
我有一个 3x3 数组: var my_array = [[0,1,2], [3,4,5], [6,7,8]]; 并想获得它的第一个 2
我意识到您可以使用如下方式轻松检查焦点: var hasFocus = true; $(window).blur(function(){ hasFocus = false; }); $(win
我是一名优秀的程序员,十分优秀!