W.I.S. Laboratory
menu-bar

C++


C++で関数をカリー化してみる

関数をカリー化するには、その言語が第一級関数をサポートしている必要がある。
要するに「関数を返す関数」が作成できることが前提となり、その返される関数がクロージャになっているか、その関数にキャプチャ機能があるか、どちらかが必要だ。
C++の関数はクロージャにはなれないが、キャプチャ機能があるラムダ式(というか関数オブジェクト)が作れるので、関数のカリー化が可能なように思える。

つまり「ラムダ式を返す関数」を定義すれば良いわけだが、「ラムダ式の型」ってなんだ?っていうことになる。
C++のラムダ式は関数オブジェクトのシンタックスシュガーなので、それぞれにクラスがあり、それが型ということになる。
クラスはコンパイラが自動生成するので、複数のラムダ式はすべて異なる型になる・・つまり「ラムダ式の型」は一定ではない。
こういうときは関数テンプレートを使うのが定番だが、std::functionでラップするとスッキリしたコードになる。(実際はテンプレートとして展開されているっぽい)
シグネチャが同じものであれば、コンパイラが複数のラムダ式を同じ型として扱ってくれるので便利だ。(C++20ならautoで良いのではあるが・・)
あとは外側関数の引数をキャプチャすれば良いのだが、これを参照キャプチャしてしまうとラムダ式が返った後に外側関数の引数がダングリングポインタの参照先になってしまうので、値キャプチャすればOKだ。

ここでは引数を2つ取り、その和を返す下のような単純な関数をカリー化してみることにする。

この関数をカリー化すると、下の「add_n_func」のような感じになる。


[ 戻る ]
saluteweb