ラムダをクラスメンバとして格納して呼び出しを延期できるようにする必要がある場合に使用するベストプラクティスは何ですか?より具体的には、以下のコードリストのクラスdeferred_lambda
に渡されたラムダを参照として格納することは安全ですか?そうでない場合は、参照としてではなく値としてdeferred_lambda
にラムダを格納することは安全でしょうか?クラスにラムダを格納する
最後に、このようにラムダをクラスメンバーとして格納するg ++の通常の関数呼び出しと比較して、パフォーマンス上のペナルティが発生すると予想できますか?つまり、deferred_lambda.invoke()
を使用すると、同じ操作を実装するいくつかのダミー構造体のoperator()
への呼び出しよりも遅くなるでしょうか?
g ++では、キャプチャされた変数を多く使うほどラムダのサイズが大きくなることに気付きました。これは私の理解によれば、コンパイラはメンバーとして必要なキャプチャされた変数を含むラムダの構造体を内部的に生成するので、これが期待されると思います。この見解は、ラムダを値で保存することは、参照を保存するよりも時間とメモリの面で高価になる可能性があるため、今質問している質問につながったのです。
template <class Func>
class deferred_lambda
{
Func& func_;
public:
deferred_lambda(Func func) : func_(func) {}
void invoke() { func_(); }
};
template <class Func>
deferred_lambda<Func> defer_lambda(Func func)
{
return deferred_lambda(func);
}
void foo()
{
int a, b, c;
auto x = defer_lambda([&]() { a = 1; b = 2; c = 3; });
}
なぜ関数オブジェクトに_reference_を格納するのかわかりません。 –
'は、同じ操作を実装するいくつかのダミー構造体でoperator()を呼び出すよりも、deferred_lambda.invoke()を使用するほうが遅くなるでしょうか?それは、とにかくlambda _is_です。 –
私の質問では、より多くのキャプチャ変数が使用されるにつれて、関数オブジェクトが大きくなる可能性があります。 –