std :: unique_ptr不是零成本

我已经设置好了,类似于:

有一个类似于vector的类(它使用std :: vector实现)。

它包含指向int的指针。

我正在使用自己的自定义分配器。

向量不会创建元素,但是会破坏元素。

要销毁它,需要调用非静态方法Allocator::deallocate(int *p)

如果通过手动实时管理进行操作,则可以手动致电Allocator::deallocate(int *p)。这有效,但RAII无效。

或者,我可以将std::unique_ptr与自定义删除器一起使用。但是,如果这样做,则数组的大小将变成两倍,因为每个std::unique_ptr必须包含指向分配器的指针。

在不增加向量大小的情况下,有什么方法可以做到吗?

请注意,我不想对课程进行模板化。

这是我出现的最好的RAII代码。

#include <functional>
#include <cstdlib>
#include <memory>



struct MallocAllocator{
    template<class T>
    static T *allocate(size_t size = sizeof(T) ) noexcept{
        return reinterpret_cast<T *>( malloc(size) );
    }

    // this is deliberately not static method
    void deallocate(void *p) noexcept{
        return ::free(p);
    }

    // this is deliberately not static method
    auto getDeallocate() noexcept{
        return [this](void *p){
            deallocate(p);
        };
    }
};



struct S{
    std::function<void(void *)> fn;

    S(std::function<void(void *)> fn) : fn(fn){}

    auto operator()() const{
        auto f = [this](void *p){
            fn(p);
        };

        return std::unique_ptr<int,decltype(f)>{ (int *) malloc(sizeof(int)),f };
    }
};



int main(){
    MallocAllocator m;

    S s{ m.getDeallocate() };

    auto x = s();

    printf("%zu\n",sizeof(x));
}
evilor110 回答:std :: unique_ptr不是零成本

您无法做到。如果您希望unique_ptr存储对非静态删除器的引用,那么您无能为力,它将不得不将其存储在某个地方。

一些解决此问题的方法:

  1. 如果您正在使用可识别分配器的数据结构,请将分配器传递给它,而不使用unique_ptr的结构,请使用实际的数据类型作为存储类型。
  2. 将您分配的对象包装在某种管理器中,该管理器将在需要时取消分配那些对象。您会在其中丢失RAII,但是对于外部代码,它仍然是RAII。您甚至可以将某些对象的所有权从该管理器转移到外部代码,而仅需在此使用自定义删除器。
  3. (不推荐)使用一些可以从deleter访问的全局状态,使其大小为0。
本文链接:https://www.f2er.com/3165810.html

大家都在问