次のように、ラムダの型をテンプレート引数として使用することができます。
template<typename InArg, typename Function>
class selfCompose {
Function f;
public:
selfCompose(Function f): f(f) {}
auto operator() (InArg x) -> decltype(f(f(x))) {
return f(f(x)); }
};
int main() {
auto f = [](int x){return x*x;};
std::cout << selfCompose<int, decltype(f)>(f)(4) // yields (4²)² = 256
<< std::endl;
return 0;
}
ただし、この二重の使用f
は一種の冗長です。ラムダの型をテンプレートとして渡すことを省略できます(適切なものにキャストしstd::function
ます(多態性が失われますが、C ++ラムダはとにかくパラメトリックに多態的ではありません))が、私はそれを渡す必要がないことを望んでいるアプリケーションがありますコンストラクターへの値(クラスの初期化自体をテンプレートパラメーターとして使用したいので、特定のコンストラクターシグネチャが必要です)。私はそれが次のように機能することを望みます
template<class InArg, class Function>
class selfCompose {
Function f;
public:
selfCompose() {} // default constructor for f
auto operator() (InArg x) -> decltype(f(f(x))) {
return f(f(x)); }
};
int main() {
auto f = [](int x){return x*x;};
std::cout << selfCompose<int, decltype(f)>()(4) << std::endl;
return 0;
}
ただし、ラムダにはデフォルトのコンストラクターが削除されているため、これはコンパイルされません。これはもちろんラムダをキャプチャするために避けられませんが、私の例のような単純なものの場合、これは私にはあまり意味がありません。ローカル変数を参照する必要はありません。
この機能を取得する他の方法はありますか、それともラムダを昔ながらの名前付きクラスとして定義することに頼る必要がありますか?
struct myFun {
auto operator() (int x) -> int {return x*x;}
};
(もちろん、私が使用したいラムダ関数はそれほど単純ではないx → x²
ので、いくつかの標準関数クラスから選択するだけでは十分な柔軟性がありません)