の実装がどのように機能するかを理解したい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>
すると、メンバーがまだ生きているため、早すぎるように思えます。