Saya mencoba untuk membangun std::thread
dengan fungsi anggota yang tidak memerlukan argumen dan pengembalian void
. Saya tidak dapat menemukan sintaks yang berfungsi - kompiler mengeluh tidak peduli apa. Apa cara yang benar untuk diterapkan spawn()
sehingga mengembalikan std::thread
yang dijalankan test()
?
#include <thread>
class blub {
void test() {
}
public:
std::thread spawn() {
return { test };
}
};
c++
multithreading
c++11
Abergmeier
sumber
sumber
std::move( std::thread(func) );
lebih baik, karenastd::thread
tidak memiliki copy-constructor.std::move
berlebihan dalam hal ini - jika ini tidak benar, dan tidak ada copy constructor, kompiler akan tetap memberikan kesalahan.Jawaban:
EDIT: Menghitung hasil edit Anda, Anda harus melakukannya seperti ini:
UPDATE: Saya ingin menjelaskan beberapa poin lagi, beberapa dari mereka juga telah dibahas dalam komentar.
Sintaks yang diuraikan di atas didefinisikan dalam istilah definisi INVOKE (§20.8.2.1):
Fakta umum lain yang ingin saya tunjukkan adalah bahwa secara default konstruktor utas akan menyalin semua argumen yang diteruskan ke sana. Alasan untuk ini adalah bahwa argumen mungkin perlu hidup lebih lama dari utas panggilan, menyalin argumen menjamin itu. Sebaliknya, jika Anda ingin benar-benar melewati referensi, Anda dapat menggunakan yang
std::reference_wrapper
dibuat olehstd::ref
.Dengan melakukan ini, Anda berjanji bahwa Anda akan memastikan bahwa argumen akan tetap ada ketika utas beroperasi pada mereka.
Perhatikan bahwa semua hal yang disebutkan di atas juga dapat diterapkan ke
std::async
danstd::bind
.sumber
std::thread
konstruktor berfungsi seolah argumen diteruskanstd::bind
. Untuk memanggil fungsi anggota, argumen pertamastd::bind
harus berupa pointer, referensi, atau pointer bersama ke objek dengan tipe yang sesuai.bind
? Saya tidak dapat menemukannya di mana pun.Karena Anda menggunakan C ++ 11, ekspresi lambda adalah solusi yang bagus & bersih.
karena
this->
dapat dihilangkan, bisa disingkat menjadi:atau hanya
sumber
std::move
ketika mengembalikan variabel lokal dengan nilai. Ini sebenarnya menghambat RVO. Jika Anda hanya kembali dengan nilai (tanpa bergerak) kompiler dapat menggunakan RVO, dan jika tidak standar mengatakan itu harus memanggil semantik bergerak.[=]
. Dengan itu Anda dapat secara tidak sengaja menyalin objek besar. Secara umum, ini bau kode untuk digunakan[&]
atau[=]
.[&]
), Anda dapat memperkenalkan bug seperti beberapa referensi yang menggantung. (Misalnya,std::thread spawn() { int i = 10; return std::thread( [&] { std::cout<<i<<"\n"; } ); }
)Ini adalah contoh lengkapnya
Kompilasi dengan g ++ menghasilkan hasil berikut
sumber
delete
memori dari tumpukan :)@ hop5 dan @RnMss menyarankan untuk menggunakan C ++ 11 lambdas, tetapi jika Anda berurusan dengan pointer, Anda dapat menggunakannya secara langsung:
output
Sampel yang ditulis ulang dari jawaban ini adalah:
sumber
Beberapa pengguna telah memberikan jawaban mereka dan menjelaskannya dengan sangat baik.
Saya ingin menambahkan beberapa hal lagi yang terkait dengan utas.
Cara bekerja dengan functor dan utas. Silakan lihat contoh di bawah ini.
Thread akan membuat salinannya sendiri dari objek saat melewati objek.
Cara lain untuk mencapai hal yang sama adalah seperti:
Tetapi jika Anda ingin melewatkan objek dengan referensi maka gunakan sintaks di bawah ini:
sumber