Jika Anda menginginkan kinerja, berikan nilai jika Anda menyimpannya.
Misalkan Anda memiliki fungsi yang disebut "jalankan ini di thread UI".
std::future<void> run_in_ui_thread( std::function<void()> )
yang menjalankan beberapa kode di utas "ui", lalu memberi sinyal futuresaat selesai. (Berguna dalam kerangka UI di mana utas UI adalah tempat Anda seharusnya mengacaukan elemen UI)
Kami memiliki dua tanda tangan yang sedang kami pertimbangkan:
std::future<void> run_in_ui_thread( std::function<void()> )
std::future<void> run_in_ui_thread( std::function<void()> const& )
Sekarang, kami cenderung menggunakan ini sebagai berikut:
run_in_ui_thread( [=]{
} ).wait();
yang akan membuat penutupan anonim (lambda), membuat std::functionkeluar darinya, meneruskannya ke run_in_ui_threadfungsi, lalu menunggu hingga selesai berjalan di utas utama.
Dalam kasus (A), std::functionsecara langsung dibangun dari lambda kami, yang kemudian digunakan dalam file run_in_ui_thread. Lambda adalah moved ke dalam std::function, sehingga setiap status bergerak secara efisien dibawa ke dalamnya.
Dalam kasus kedua, sementara std::functiondibuat, lambda moved ke dalamnya, kemudian sementara std::functionitu digunakan sebagai referensi dalam file run_in_ui_thread.
Sejauh ini, sangat bagus - keduanya tampil identik. Kecuali run_in_ui_threadakan membuat salinan argumen fungsinya untuk dikirim ke utas ui untuk dieksekusi! (itu akan kembali sebelum selesai dengannya, jadi tidak bisa hanya menggunakan referensi ke sana). Untuk kasus (A), kami hanya movememasukkan std::functionke dalam penyimpanan jangka panjangnya. Dalam kasus (B), kami dipaksa untuk menyalin file std::function.
Penyimpanan itu membuat nilai lewat lebih optimal. Jika ada kemungkinan Anda menyimpan salinan dari nilai std::functionlewat. Jika tidak, cara mana pun secara kasar setara: satu-satunya sisi negatif dari nilai sampingan adalah jika Anda menggunakan ukuran besar yang sama std::functiondan memiliki satu sub metode setelah yang lain menggunakannya. Kecuali itu, a moveakan seefisien a const&.
Sekarang, ada beberapa perbedaan lain antara keduanya yang kebanyakan muncul jika kita memiliki status persisten di dalam std::function.
Asumsikan bahwa std::functionmenyimpan beberapa objek dengan a operator() const, tetapi juga memiliki beberapa mutableanggota data yang dimodifikasi (betapa kasarnya!).
Dalam std::function<> const&kasus ini, mutableanggota data yang dimodifikasi akan menyebar keluar dari pemanggilan fungsi. Dalam std::function<>kasus ini, mereka tidak akan melakukannya.
Ini adalah kasus sudut yang relatif aneh.
Anda ingin memperlakukan std::functionseperti Anda memperlakukan jenis lain yang mungkin berbobot berat dan dapat dipindahkan dengan murah. Pindahan itu murah, menyalin bisa mahal.
sizeof(std::function)tidak lebih dari2 * sizeof(size_t), yang merupakan ukuran terkecil yang pernah Anda pertimbangkan untuk referensi const.