コンパイル時に評価可能なラムダ式であるかを判定する
はじめに
なんとなく、与えられたラムダ式がコンパイル時に評価可能であるかを判定して実行時には静的な部分と動的な部分を適宜組み合わせたハイブリッドな実装をしたくなることがあるだろう。そして、ざっくりと検索をすると以下の質問とその回答がヒットし、それっぽい実装に出会えた感じになる。
その実装部を以下に転記する。これは単にSFINAEによりコンパイル時に呼び出し可能であるかを試みて処理を切り替えるというものである。
しかし、この実装ではラムダ式が変数をキャプチャしている場合にコンパイル時に判定をすることができないし、引数をもつラムダ式には対応していない。あと、メタ関数やconceptsで利用したいという自分の需要も満たさない。そこで、疑似的に与えられたラムダ式がコンパイル時に評価可能であるかを判定するメタ関数を作成する。
実装
別に実装としてはそこまで複雑ではないため早速以下に実装を示す。まず、キャプチャのないラムダ式は単なる関数オブジェクトであり、デフォルト構築が可能である。そのため、デフォルト構築可能か否かで分岐をし、あとは上記で示したis_constexpr
の仕組み(SFINAE)を用いて判定するだけである。また、Lambda::operator()
により関数オブジェクトについてのメンバ関数ポインタを取得して、ここから引数型を取得して引数の判定を可能にしている。ただし、ラムダ式の引数はデフォルト構築が可能であることを仮定している。
実際のこれの利用例は以下である。ポイントとしては、関数の引数にラムダ式を設定しないことである。これにより、コンパイル時の評価が可能となる。
おわりに
現実的な用途としては、もう少し一般化して実装をしてもいいが、自分としてはこれで十分であるため、これ以上の一般化は必要になるまで考えないつもりである。