简体   繁体   English

带有新位置的 std::make_unique

[英]std::make_unique with placement new

I'm trying to define a Data object that contains its size, followed by size bytes of data.我正在尝试定义一个包含其大小的Data object,然后是数据的size字节。

Something like:就像是:

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

This works, and I can allocate it with placement new:这行得通,我可以将其分配给新的位置:

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

I'd like to create a std::unique_ptr<Data> and, as good practice , I'd prefer to use std::make_uinque , over a raw new .我想创建一个std::unique_ptr<Data> ,并且作为一种好的做法,我更喜欢使用std::make_uinque ,而不是原始的new

Is it possible to call std::make_unique<Data> passing it the data for placement-new?是否可以调用std::make_unique<Data>将数据传递给placement-new?

Any version of the C++ standard is fine. C++ 标准的任何版本都可以。

There is no standard way to do this, because standard C++ doesn't provide any real support for VLAs/flexible array members.没有标准的方法可以做到这一点,因为标准的 C++ 没有为 VLA/灵活数组成员提供任何真正的支持。 make_unique was written solely for either: make_unique仅用于以下任一目的:

  1. A single object of fixed size (it has no mechanism to provide information about the "real" size, it just uses new , which assumes sizeof T is correct and complete)固定大小的单个 object (它没有提供有关“真实”大小信息的机制,它只是使用new ,假设sizeof T是正确且完整的)
  2. An array of objects of fixed size (by definition an array must have objects of fixed size, or indexing doesn't work)固定大小的对象数组(根据定义,数组必须具有固定大小的对象,否则索引不起作用)

I suppose in theory you could make your own version that supported quasi-flexible array members, but there is zero support for this in the C++ standard library.我想理论上你可以制作自己的支持准灵活数组成员的版本,但在 C++ 标准库中对此的支持为零 std::make_unique doesn't even have an allocator-aware variant; std::make_unique甚至没有分配器感知变体; it's not going out of its way to support unusual use cases.它不会竭尽全力支持不寻常的用例。 std::allocate_shared (the allocator aware version of std::make_shared ) might be forced to support this in ridiculous ways (you'd essentially need to write custom allocators that also knew how much extra memory an allocation request should provide), and there's a proposal for an allocator-aware version of std::make_unique , but again, making this work would be an exercise in insanity. std::allocate_shared (分配器感知版本的std::make_shared )可能会被迫以荒谬的方式支持这一点(您基本上需要编写自定义分配器,这些分配器知道分配请求应该提供多少额外的 memory),并且有一个关于分配器感知版本的std::make_unique的提议,但同样,使这项工作成为一种精神错乱的练习。

You say "as good practice, I'd prefer to use std::make_unique , over a raw new ", but flexible array members in C++ are already bad practice;您说“作为一种好的做法,我更喜欢使用std::make_unique ,而不是原始的new ”,但是 C++ 中的灵活数组成员已经是不好的做法; there is essentially zero support for them because they break all sorts of assumptions that much of the C++ language and library rely on.对它们的支持基本上为零,因为它们打破了许多 C++ 语言和库所依赖的各种假设。 If you must do it, write your own factory methods to perform the work;如果必须这样做,请编写自己的工厂方法来执行工作; sure, using raw new is frowned on, but confining it to a single API in your code that guarantees the result is a managed pointer before passing it outside that API limits the "damage".当然,不赞成使用 raw new ,但是将其限制在代码中的单个 API 以保证结果是托管指针,然后再将其传递到 API 之外,从而限制了“损坏”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM