Performans istiyorsanız, saklıyorsanız değere göre geçin.
"Bunu UI iş parçacığında çalıştır" adında bir işleve sahip olduğunuzu varsayalım.
std::future<void> run_in_ui_thread( std::function<void()> )
"ui" iş parçacığında bazı kodlar çalıştırılır, sonra future
ne zaman yapıldığına işaret eder . (UI iş parçacığının UI öğeleriyle uğraşmanız gereken yerlerde UI çerçevelerinde kullanışlıdır)
Düşündüğümüz iki imzamız var:
std::future<void> run_in_ui_thread( std::function<void()> ) // (A)
std::future<void> run_in_ui_thread( std::function<void()> const& ) // (B)
Şimdi bunları muhtemelen şu şekilde kullanacağız:
run_in_ui_thread( [=]{
// code goes here
} ).wait();
anonim bir kapatma (lambda) oluşturacak, bir std::function
dışarı oluşturacak, run_in_ui_thread
işleve geçirecek ve daha sonra ana iş parçacığında çalışmasını bitirmesini bekleyecektir.
(A) durumunda std::function
, doğrudan lambdadan yapılır, daha sonra içinde kullanılır run_in_ui_thread
. Lambda, move
içine girer std::function
, bu nedenle herhangi bir hareketli durum etkili bir şekilde içine taşınır.
İkinci durumda, bir geçici std::function
yaratılır, lambda move
içine girilir , daha sonra bu geçici std::function
, içinde referans olarak kullanılır run_in_ui_thread
.
Şimdiye kadar, çok iyi - ikisi aynı performans gösteriyor. Dışında run_in_ui_thread
işlevi argüman bir kopyasını yapacak yürütmek için ui iplik göndermek için! (onunla yapılmadan önce geri dönecektir, bu yüzden sadece bir referans kullanamaz). Durumda, (A) için, basitçe uzun vadeli depoya. (B) durumunda, kopyalamak zorunda kalırız .move
std::function
std::function
Bu mağaza, değere göre geçişi daha uygun hale getirir. Bir kopyasını saklamak için herhangi bir olasılık varsa, std::function
değere göre geçin. Aksi takdirde, her iki yol da kabaca eşdeğerdir: by-value için tek dezavantaj, aynı hantal std::function
alıp başka bir kullanımdan sonra bir alt yönteme sahip olmanızdır . Bunu engellemek, a move
kadar etkili olacaktır const&
.
Şimdi, ikisinin arasında, içinde kalıcı bir durumumuz varsa çoğunlukla devreye giren başka bazı farklılıklar var std::function
.
std::function
Bir nesneyi a ile sakladığını operator() const
, ancak mutable
değiştirdiği (ne kadar kaba!) Bazı veri üyelerine sahip olduğunu varsayın .
Bu std::function<> const&
durumda, mutable
değiştirilen veri üyeleri işlev çağrısından yayılır. In std::function<>
durumunda, bunlar olmaz.
Bu nispeten garip bir köşe davası.
std::function
Muhtemelen ağır, ucuza hareket eden başka bir şeymiş gibi davranmak istersiniz. Taşınma ucuz, kopyalama pahalı olabilir.
sizeof(std::function)
daha fazla olmayı beklerdim2 * sizeof(size_t)
, bu bir const referansı için düşündüğünüz en az boyut.