私はboost::variant
、この質問をする必要がなく、使用できることを知っています。しかし、使用boost::variant
には多くの醜いコードが含まれます。特に来客はごちゃごちゃ。だから、これ以上苦労せずに...
カリー化された関数の遅延評価を実装するために、次のテンプレート化されたクラスを作成しました。(スニペット全体については、以前の質問を参照してください。)
template <typename> class curry;
template <typename _Res>
class curry< _Res() >
{
public:
typedef std::function< _Res() > _Fun;
typedef _Res _Ret;
private:
_Fun _fun;
public:
explicit curry (_Fun fun)
: _fun(fun) { }
operator _Ret ()
{ return _fun(); }
};
そのため、メモ化を含めるように更新したいと思います。概念的には、非常に単純です。まず、次のものを交換する必要があります。
private:
_Fun _fun;
public:
explicit curry (_Fun fun)
: _fun(fun) { }
と:
private:
bool _evaluated; // Already evaluated?
union
{
_Fun _fun; // No
_Res _res; // Yes
};
public:
explicit curry (_Fun fun)
: _evaluated(false), _fun(fun) { }
explicit curry (_Res res)
: _evaluated(true), _res(res) { }
しかし、あと2つ残っています。operator _Ret
まず、遅延評価を実行する場合、結果が実際にメモ化されるように更新する必要があります。次に、デストラクタを追加して、 の値に応じてまたはが破棄されるよう_evaluated
にする必要があります。そして、ここで私は物事を行う方法についてよくわかりません。_fun
_res
_fun
まず、これはに置き換える正しい方法_res
ですか? そうでない場合は、どうすればよいですか?
operator _Ret ()
{
if (!_evaluated) {
_Fun fun = _fun;
// Critical two lines.
_fun.~_Fun();
_res._Res(fun());
_evaluated = true;
}
return _res;
}
第二に、これは選択的に破壊する正しい方法_fun
ですか_res
? そうでない場合は、どうすればよいですか?
~curry ()
{
if (_evaluated)
_res.~_Res();
else
_fun.~_Fun();
}