パフォーマンスが必要な場合は、格納する場合は値で渡します。
「これをUIスレッドで実行する」という関数があるとします。
std::future<void> run_in_ui_thread( std::function<void()> )
「ui」スレッドでいくつかのコードを実行しfuture
、完了時にを通知します。(UIスレッドがUI要素をいじるはずの場所にあるUIフレームワークで役立ちます)
検討しているシグネチャは2つあります。
std::future<void> run_in_ui_thread( std::function<void()> ) // (A)
std::future<void> run_in_ui_thread( std::function<void()> const& ) // (B)
現在、これらを次のように使用する可能性があります。
run_in_ui_thread( [=]{
// code goes here
} ).wait();
これは匿名のクロージャー(ラムダ)を作成std::function
し、それからoutを作成し、それをrun_in_ui_thread
関数に渡し、メインスレッドで実行が完了するのを待ちます。
(A)の場合、std::function
はラムダから直接作成され、内で使用されますrun_in_ui_thread
。ラムダはにmove
組み込まれているstd::function
ので、あらゆる可動状態が効率的にそこに運ばれます。
2番目のケースでは、一時的な std::function
が作成され、ラムダがmove
それに挿入され、そのテンポラリstd::function
が内で参照によって使用されますrun_in_ui_thread
。
これまでのところ、非常に優れています。2つは同じように動作します。を除いて、run_in_ui_thread
実行するためにuiスレッドに送信する関数引数のコピーを作成します!(処理が完了する前に戻るため、参照を使用することはできません)。ケース(A)の場合、単純にmove
std::function
その長期保存に。ケース(B)では、をコピーする必要がありstd::function
ます。
そのストアは、値による受け渡しをより最適にします。のコピーを保存している可能性がある場合はstd::function
、値で渡します。それ以外の場合、どちらの方法もほぼ同じです。値渡しの唯一の欠点は、同じかさばるstd::function
、サブメソッドを次々に使用する場合です。それを除けば、aはとmove
同じくらい効率的const&
です。
さて、2つの間には他にもいくつかの違いがあります。これらの違いは、内に永続的な状態がある場合に主に発生しstd::function
ます。
は、std::function
いくつかのオブジェクトをで保存するとしますが、変更するデータメンバーoperator() const
もいくつか持っているものとしmutable
ます(失礼です)。
このstd::function<> const&
場合、mutable
変更されたデータメンバーは関数呼び出しから伝達されます。そのstd::function<>
場合、彼らはしません。
これは比較的奇妙なコーナーケースです。
あなたstd::function
は、他のおそらくヘビー級の安価な可動タイプと同じように扱いたいです。移動は安く、コピーは高価になる可能性があります。
sizeof(std::function)
以上ないことを期待します2 * sizeof(size_t)
。