c++ - 像 std::function 这样的自毁类型删除类是如何实现的?

标签 c++ type-erasure self-destruction

我想了解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通过这个(需要返回一个指针)。

现在,我们来看看非标准解决方案:如果您习惯使用 allocavariable 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/

相关文章:

c++ - 如何在运算符重载中解释 "operator const char*()"?

c++ - 如何编写以负数结尾的循环 (MyProgrammingLab 11138)

windows - Linux Bash 和 Windows Batch 的自删除脚本

java - 无法构造泛型类型参数,该怎么办?

ios - Swift:嵌套类型删除

c++ - 应该从成员方法中调用 "delete this"吗?

c++ - 我的代码在删除这个时崩溃

c++ - 将数据加载到结构 vector 中

c++ - 我在这个 C++ 代码中有错误吗?

java - 类型删除后何时转换函数的通用返回值?