标准::aligned_storage 中的新放置
Placement new in std::aligned_storage?
假设我有一个类型模板参数 T。
假设我有一个如下std::aligned_storage
:
typename std::aligned_storage<sizeof(T), alignof(T)>::type storage;
我想在storage
中放置新的 T .
要传递给放置新运算符的符合标准的指针值/类型是什么,如何从storage
派生?
new (& ???) T(a,b,c);
例如:
new (&storage) T(a,b,c);
new (static_cast<void*>(&storage)) T(a,b,c);
new (reinterpret_cast<T*>(&storage)) T(a,b,c);
new (static_cast<T*>(static_cast<void*>(&storage));
以上哪项(如果有)是合规的,如果没有,更好的方法是什么?
最偏执的方式是
::new ((void *)::std::addressof(storage)) T(a, b, c);
解释:
-
::std::addressof
防止storage
上过载的一元operator&
,这是标准在技术上允许的。(尽管没有理智的实现可以做到这一点。该::std
可防止任何可能位于范围内的称为std
的非顶级命名空间(或类)。 -
(void *)
(在这种情况下相当于static_cast
)确保您将放置称为operator new
采用void *
而不是其他类似decltype(storage) *
。 -
::new
跳过任何特定于类的放置operator new
s,确保调用转到全局放置。
总之,这保证了调用在void *
operator new
转到库放置,并且T
是在storage
所在的位置构造的。
然而,在大多数理智的程序中,
new (&storage) T(a,b,c);
应该足够了。
放置分配函数描述如下 (C++14 n4140 18.6.1.3):
void* operator new(std::size_t size, void* ptr) noexcept;
返回:
ptr
.备注:故意不执行其他操作。
20.10.7.6 表57这样描述aligned_storage<Len, Align>
:
成员类型定义
type
应为适合使用的 POD 类型 作为任何对象的未初始化存储 谁的大小最多是 Len 和谁 对齐是对齐的除数。
这意味着在您的情况下,&storage
适合放置类型 T
的对象。因此,在正常情况下1,您列出的所有 4 种调用放置new
的方式都是有效且等效的。为了简洁起见,我会使用第一个(new (&storage)
)。
1 T.C. 在评论中正确地指出,从技术上讲,您的程序可以声明分配typename std::aligned_storage<sizeof(T), alignof(T)>::type*
函数的重载,然后通过重载分辨率而不是库提供的"放置新"版本来选择。
我会说这在至少 99.999% 的情况下不太可能,但如果您还需要防范这种情况,请使用其中一个强制void*
。直接static_cast<void*>(&storage)
就足够了。
此外,如果你偏执到这个级别,你可能应该使用::new
而不是仅仅new
来绕过任何特定于类的分配函数。
- 使用新行和不使用新行读取文件
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 遇到新行时,有没有办法停止istream_iterator
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 计算缩放多边形的比例,得到给定的多边形面积
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- QwtPlot具有相等的轴和自动缩放
- 如何在directx/c++中进行平移/缩放操作
- 模板元编程:如何将参数包组合成新的参数包
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 我可以将新的 std::tuple 放入内存映射区域,并在以后读回吗?
- C++,打开和编辑文本文件中的数字数据,并将结果放入新文件中
- 将 int 放入 char 数组是否在法律上需要新的放置
- 如何将未排序数组的排序索引放入新数组中
- 视觉计数重复,并将唯一条目放入数组 [C++] 中的新数组中
- c++将行getline放入数组中,用新行分隔
- 读取文件夹中的所有文件,然后将每个文件及其匹配项放入新的excel文档中.是否可以用c++
- Visual Studio将新文件放入错误的目录中