【发布时间】:2016-06-27 09:46:57
【问题描述】:
我想了解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> 的析构函数中释放,那似乎还为时过早,因为它的成员还活着。
【问题讨论】:
-
请注意,在 C++17 中将删除对
std::function的分配器支持。
标签: c++ type-erasure self-destruction