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 future
saat 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::function
keluar darinya, meneruskannya ke run_in_ui_thread
fungsi, lalu menunggu hingga selesai berjalan di utas utama.
Dalam kasus (A), std::function
secara langsung dibangun dari lambda kami, yang kemudian digunakan dalam file run_in_ui_thread
. Lambda adalah move
d ke dalam std::function
, sehingga setiap status bergerak secara efisien dibawa ke dalamnya.
Dalam kasus kedua, sementara std::function
dibuat, lambda move
d ke dalamnya, kemudian sementara std::function
itu digunakan sebagai referensi dalam file run_in_ui_thread
.
Sejauh ini, sangat bagus - keduanya tampil identik. Kecuali run_in_ui_thread
akan 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 move
memasukkan std::function
ke 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::function
lewat. Jika tidak, cara mana pun secara kasar setara: satu-satunya sisi negatif dari nilai sampingan adalah jika Anda menggunakan ukuran besar yang sama std::function
dan memiliki satu sub metode setelah yang lain menggunakannya. Kecuali itu, a move
akan 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::function
menyimpan beberapa objek dengan a operator() const
, tetapi juga memiliki beberapa mutable
anggota data yang dimodifikasi (betapa kasarnya!).
Dalam std::function<> const&
kasus ini, mutable
anggota 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::function
seperti 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.