voi*_*xb3 5 c++ undefined-behavior allocator language-lawyer c++17
我正在尝试编写一个分配器感知容器。假设我想为三个对象分配一块内存:
T* chunk = std::allocator_traits<Allocator>::allocate(allocator, 3);
Run Code Online (Sandbox Code Playgroud)
(我知道分配器可以有自定义指针类型,因此我应该使用std::allocator_traits<Allocator>::pointer
;为了简单起见,我在这里使用原始指针。)
现在我想在索引 2 处创建一个实际对象。我该怎么做?特别是,如何计算指向尚不存在的元素的指针?最明显的选项如下:
std::allocator_traits<Allocator>::construct(allocator, chunk + 2, ...);
Run Code Online (Sandbox Code Playgroud)
不幸的是,chunk + 2
似乎并不正确:根据标准,指针运算只能对指向数组元素的指针执行,否则会导致未定义的行为。出于同样的原因,我无法将指针转换为指针std::byte*
并对其使用指针算法。(虽然std::allocator
定义为在新分配的内存中创建数组,但在 C++20 之前,自定义分配器不存在相同的要求。此外,虽然 C++20 增加了一些“隐式创建对象”的语言,但这并没有申请较早的 C++ 版本。)
那么如何计算要作为第二个参数给出的指针construct
而不导致未定义的行为(在 C++20 之前)?
在最新的标准草案(C++20)中:
[选项卡:cpp17.分配器]
a.allocate(n) - 为n T 的数组分配内存,并创建这样的对象,但不构造数组元素。
allocator_traits::allocate(n)
只需调用a.allocate(n)
.
因此,鉴于创建了数组,指针算术已明确定义。
在接受提案 P0593R6 之前的 C++17 中,写法是:
创建了 n 个类型为 T 的对象,但未构造对象,因此分配了内存。
在此更改之前,没有明确的方法来执行您所要求的操作,除非:
归档时间: |
|
查看次数: |
193 次 |
最近记录: |