今の仕組みのまま、特別な拡張なしにクロージャを実現できないか考えてみました。結論から言うと見送りですが、せっかく検討したので記録を残しておきます。
関数と構造体
関数のスタックフレームをローカル変数の構造体だと考えれば、関数と関数オブジェクトは同じになりそうです。
関数のスタック構造 |
---|
引数 |
ret先 |
EBP(退避) |
ローカル変数 |
ワークエリア |
ローカル変数を構造体のメンバと見なすわけです。そうなると内部的に関数を構造体として処理できるので、構造体とブロックを統合できるかもしれません。
thiscall
この考え方で関数オブジェクトを作ると、ローカル変数を構造体として任意の場所に確保することになります。それがスタックであれば従来の関数と同じです。
ヒープならポインタを通知する必要があります。これはまるっきりthiscallそのものです。C++に例えると、普通の関数を関数オブジェクトに変換する場合に、ローカル変数をすべてメンバにしてしまうことに相当します。
// 関数 int Func() { int a = 2, b = 3; return a + b; } // 関数オブジェクト class { private: int a, b; public: int operator()() { a = 2; b = 3; return a + b; } } FuncObject;
すべての関数を関数オブジェクトとして生成すれば、手動で関数オブジェクトを定義する手間は省けます。しかしC言語に渡せなくなります。