我想了解std::function
是如何执行的作品。为简单起见,让我们考虑不带参数的仅移动函数。
我明白 std::function
通过典型的类型删除技术删除其目标的类型:
template<class Result>
struct function
{
public:
template<class Function>
function(Function&& f)
: f_(std::make_unique<callable_base>(std::forward<Function>(f)))
{}
// XXX how to implement constructor with allocator?
template<class Alloc, class Function>
function(const Alloc& alloc, Function&& f);
Result operator()() const
{
return (*f_)();
}
private:
struct callable_base
{
virtual Result operator()() const = 0;
virtual ~callable_base(){}
};
template<class Function>
struct callable
{
mutable Function f;
virtual Result operator()() const
{
return f;
}
};
// XXX what should the deleter used below do?
struct deleter;
std::unique_ptr<callable_base, deleter> f_;
};
我想扩展此类型的功能以支持自定义分配。我需要删除分配器的类型,但是使用 std::unique_ptr
很难做到这一点。 .给 unique_ptr
的自定义删除器需要知道 Function
的具体类型提供给构造函数,以便能够正确地释放其存储空间。我可以使用另一个 unique_ptr
键入删除删除器,但该解决方案是循环的。
好像callable<Function>
需要释放自己。正确的方法是什么?如果我在 callable<Function>
内部解除分配的析构函数,这似乎太早了,因为它的成员还活着。
最佳答案
我认为不可能以可移植的方式做到这一点,仅依赖提供的内存管理分配器。
我一直在寻找 std::shared_ptr
的实现,因为它支持 type erasure also for it's deleter and allocator (see overload 6) : 在 an sketch implementation I found around here有一个用于存储这些拷贝的辅助对象,但该对象是使用 operator new
分配的,并使用 operator delete
释放的,因此绕过了提供的分配器和删除器。
我正在考虑使用分配器的临时拷贝(在堆栈上)以释放存储的分配器(从中创建拷贝)以及存储的对象。问题是:当您不知道类型时,如何在不使用 new
/delete
的情况下获取拷贝?不幸的是,covariance is ruled out通过这个(需要返回一个指针)。
现在,我们来看看非标准解决方案:如果您习惯使用 alloca
或 variable length arrays ,那么你可以有一个删除器,在堆栈上创建一个足够大的内存区域,并让存储的分配器在该内存中创建一个自己的拷贝。这个堆栈分配(因此自动存储持续时间)拷贝可以释放存储的分配器和存储的对象,并最终被删除函数销毁(这就是所有这一切的重点,不知道分配器的具体类型).粗略的草图:
struct aux_base {
// also provide access to stored function
virtual size_t my_size(void) const = 0;
virtual aux_base * copy_in(void * memory) const = 0;
virtual void free(void * ptr) = 0;
virtual ~aux_base() {}
};
template<class Alloc, class Function>
struct aux : public aux_base {
// Store allocator and function here
size_t my_size(void) const {
return sizeof(*this);
}
aux_base * copy_in(void * memory) const {
// attention for alignment issues!
return new (memory) aux(*this);
}
void free(void * ptr) {
aux * stored = reinterpret_cast<aux *>(ptr);
// do your stuff
}
};
void deleter_for_aux(aux_base * ptr) {
char memory[ptr->my_size()];
aux_base * copy = ptr->copy_in(memory);
copy->free(ptr);
copy->~aux_base(); // call destructor
}
就是说,如果有一种方法可以在标准 C++ 中执行此操作而不依赖于所提供的分配器之外的其他动态内存源,我将非常高兴知道它! :)
关于c++ - 像 std::function 这样的自毁类型删除类是如何实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35952237/