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 );
}
};

这是有效的,我可以用新的位置分配它:

Data* data = new (3) Data( 3 );

我想创建一个std::unique_ptr<Data>,作为一个好的实践,我更喜欢使用std::make_uinque,而不是原始的new

是否可以调用std::make_unique<Data>,将放置新的数据传递给它?

任何版本的C++标准都可以。

没有标准的方法可以做到这一点,因为标准C++没有为VLA/灵活的数组成员提供任何真正的支持。make_unique仅为以下任一项编写:

  1. 固定大小的单个对象(它没有提供关于"真实"大小的信息的机制,它只使用new,它假设sizeof T是正确和完整的(
  2. 固定大小对象的数组(根据定义,数组必须具有固定大小的对象,否则索引不起作用(

我想理论上你可以制作自己的版本来支持准灵活的数组成员,但在C++标准库中对这一点的支持为零。std::make_unique甚至没有一个可识别分配器的变体;它不会特意支持不寻常的用例。std::allocate_shared(std::make_shared的分配器感知版本(可能会被迫以荒谬的方式支持这一点(您基本上需要编写自定义分配器,知道分配请求应该提供多少额外内存(,并且有人建议使用std::make_unique的分配器感知版本,但同样,实现这一功能将是一种疯狂的练习。

你说";作为良好的实践,我更喜欢使用std::make_unique而不是原始new〃;,但是C++中的灵活数组成员已经是不好的做法;它们基本上没有任何支持,因为它们打破了大部分C++语言和库所依赖的各种假设。如果必须这样做,可以编写自己的工厂方法来执行这项工作;当然,使用原始new是不受欢迎的,但在将结果传递到API之外之前,将其限制在代码中的单个API中,以确保结果是托管指针;损坏";。

相关内容

  • 没有找到相关文章

最新更新