std::make_unique 展示位置为新
std::make_unique with placement new
我正在尝试定义一个包含其大小的 Data
对象,后跟 size
字节的数据。
类似于:
struct Data {
size_t size;
char data[1];
static void* operator new( std::size_t size, size_t dataSize ) {
return ::operator new( size+dataSize-1 );
}
static void operator delete( void* data ){
::operator delete( data );
}
Data( size_t size ) : size(size) {
std::memset( data, 0, size );
}
};
这行得通,我可以用 placement new 分配它:
Data* data = new (3) Data( 3 );
我想创建一个 std::unique_ptr<Data>
和 ,我更愿意使用 std::make_uinque
,而不是原始的 new
。
是否可以调用 std::make_unique<Data>
将数据传递给它以进行新放置?
任何版本的 C++ 标准都可以。
没有执行此操作的标准方法,因为标准 C++ 不提供对 VLAs/flexible 数组成员的任何实际支持。 make_unique
专为以下两者之一编写:
- 固定大小的单个对象(它没有机制提供有关“真实”大小的信息,它只是使用
new
,假设 sizeof T
是正确和完整的)
- 固定大小的对象数组(根据定义,数组必须具有固定大小的对象,否则索引不起作用)
我想理论上您可以制作自己的支持准灵活数组成员的版本,但在 C++ 标准库中有 zero 对此的支持。 std::make_unique
甚至没有分配器感知变体;它不会特意支持不寻常的用例。 std::allocate_shared
(std::make_shared
的分配器感知版本)可能被迫以荒谬的方式支持这一点(你基本上需要编写 也 知道的自定义分配器分配请求应该提供更多的额外内存),并且 there's a proposal for an allocator-aware version of std::make_unique
,但同样,完成这项工作将是一种疯狂的练习。
你说“作为一种好的做法,我更愿意使用 std::make_unique
,而不是原始的 new
”,但是 C++ 中的灵活数组成员已经是不好的做法;对它们的支持基本上为零,因为它们打破了许多 C++ 语言和库所依赖的各种假设。如果您必须这样做,请编写自己的工厂方法来执行该工作;当然,使用原始 new
是不受欢迎的,但是将它限制在代码中的单个 API 以保证结果是一个托管指针,然后再将其传递到 API 之外限制“损坏” .
我正在尝试定义一个包含其大小的 Data
对象,后跟 size
字节的数据。
类似于:
struct Data {
size_t size;
char data[1];
static void* operator new( std::size_t size, size_t dataSize ) {
return ::operator new( size+dataSize-1 );
}
static void operator delete( void* data ){
::operator delete( data );
}
Data( size_t size ) : size(size) {
std::memset( data, 0, size );
}
};
这行得通,我可以用 placement new 分配它:
Data* data = new (3) Data( 3 );
我想创建一个 std::unique_ptr<Data>
和 std::make_uinque
,而不是原始的 new
。
是否可以调用 std::make_unique<Data>
将数据传递给它以进行新放置?
任何版本的 C++ 标准都可以。
没有执行此操作的标准方法,因为标准 C++ 不提供对 VLAs/flexible 数组成员的任何实际支持。 make_unique
专为以下两者之一编写:
- 固定大小的单个对象(它没有机制提供有关“真实”大小的信息,它只是使用
new
,假设sizeof T
是正确和完整的) - 固定大小的对象数组(根据定义,数组必须具有固定大小的对象,否则索引不起作用)
我想理论上您可以制作自己的支持准灵活数组成员的版本,但在 C++ 标准库中有 zero 对此的支持。 std::make_unique
甚至没有分配器感知变体;它不会特意支持不寻常的用例。 std::allocate_shared
(std::make_shared
的分配器感知版本)可能被迫以荒谬的方式支持这一点(你基本上需要编写 也 知道的自定义分配器分配请求应该提供更多的额外内存),并且 there's a proposal for an allocator-aware version of std::make_unique
,但同样,完成这项工作将是一种疯狂的练习。
你说“作为一种好的做法,我更愿意使用 std::make_unique
,而不是原始的 new
”,但是 C++ 中的灵活数组成员已经是不好的做法;对它们的支持基本上为零,因为它们打破了许多 C++ 语言和库所依赖的各种假设。如果您必须这样做,请编写自己的工厂方法来执行该工作;当然,使用原始 new
是不受欢迎的,但是将它限制在代码中的单个 API 以保证结果是一个托管指针,然后再将其传递到 API 之外限制“损坏” .