std::bind
adalah untuk aplikasi fungsi parsial .
Artinya, misalkan Anda memiliki objek fungsi f
yang membutuhkan 3 argumen:
f(a,b,c);
Anda menginginkan objek fungsi baru yang hanya membutuhkan dua argumen, yang didefinisikan sebagai:
g(a,b) := f(a, 4, b);
g
adalah "aplikasi parsial" dari fungsi tersebut f
: argumen tengah telah ditentukan, dan masih ada dua yang tersisa.
Anda bisa menggunakan std::bind
untuk mendapatkan g
:
auto g = bind(f, _1, 4, _2);
Ini lebih ringkas daripada menulis kelas functor untuk melakukannya.
Ada contoh lebih lanjut di artikel yang Anda tautkan. Anda biasanya menggunakannya saat Anda perlu meneruskan functor ke beberapa algoritme. Anda memiliki fungsi atau functor yang hampir melakukan pekerjaan yang Anda inginkan, tetapi lebih dapat dikonfigurasi (yaitu memiliki lebih banyak parameter) daripada yang digunakan algoritme. Jadi, Anda mengikat argumen ke beberapa parameter, dan membiarkan sisanya untuk diisi oleh algoritme:
// raise every value in vec to the power of 7
std::transform(vec.begin(), vec.end(), some_output, std::bind(std::pow, _1, 7));
Di sini, pow
mengambil dua parameter dan dapat menaikkan ke daya apa pun , tetapi yang kami pedulikan hanyalah meningkatkan ke pangkat 7.
Sebagai penggunaan sesekali yang bukan merupakan aplikasi fungsi parsial, bind
juga dapat menyusun ulang argumen ke suatu fungsi:
auto memcpy_with_the_parameters_in_the_right_flipping_order = bind(memcpy, _2, _1, _3);
Saya tidak menyarankan menggunakannya hanya karena Anda tidak menyukai API, tetapi memiliki potensi penggunaan praktis misalnya karena:
not2(bind(less<T>, _2, _1));
adalah fungsi kurang dari atau sama (dengan asumsi urutan total, bla bla). Contoh ini biasanya tidak diperlukan karena sudah ada std::less_equal
(ini menggunakan <=
operator daripada <
, jadi jika mereka tidak konsisten maka Anda mungkin memerlukan ini, dan Anda mungkin juga perlu mengunjungi penulis kelas dengan klik). Ini adalah jenis transformasi yang muncul jika Anda menggunakan gaya pemrograman fungsional.
myThread=boost::thread(boost::bind(&MyClass::threadMain, this))
std::function
?pow
Contoh Anda tidak dapat dikompilasi. Karenapow
merupakan fungsi yang kelebihan beban, Anda harus menentukan kelebihan beban secara manual. Pengikatan tidak dapat meninggalkannya untuk disimpulkan oleh pemanggil dari functor yang dihasilkan. Misalnyastd::transform(vec.begin(), vec.end(), out.begin(), std::bind((double (*)(double, int))std::pow, _1, 7));
std::bind
muncul bersamaan denganthis
penggunaan sebagai argumen ke-2. Bisakah Anda menjelaskan kasus penggunaan ini?std::placeholders::_1
. Butuh beberapa saat untuk mencari tahu mengapa ini tidak bisa dikompilasi.Salah satu penggunaan utama std :: function dan std :: bind adalah sebagai pointer fungsi yang lebih umum. Anda dapat menggunakannya untuk mengimplementasikan mekanisme callback. Salah satu skenario populer adalah Anda memiliki beberapa fungsi yang akan membutuhkan waktu lama untuk dieksekusi tetapi Anda tidak ingin menunggu untuk kembali, maka Anda dapat menjalankan fungsi itu pada utas terpisah dan memberikannya penunjuk fungsi yang akan dijalankan. callback setelah selesai.
Berikut adalah contoh kode untuk menggunakan ini:
sumber
std :: bind dipilih ke dalam library setelah proposal untuk menyertakan boost bind, terutama itu adalah spesialisasi fungsi parsial di mana Anda dapat memperbaiki beberapa parameter dan mengubah yang lain dengan cepat. Sekarang ini adalah cara pustaka untuk melakukan lambda di C ++. Seperti yang dijawab oleh Steve Jessop
Sekarang C ++ 11 mendukung fungsi lambda, saya tidak merasakan godaan untuk menggunakan std :: bind lagi. Saya lebih suka menggunakan kari (spesialisasi parsial) dengan fitur bahasa daripada fitur perpustakaan.
Objek std :: function adalah fungsi polimorfik. Ide dasarnya adalah untuk dapat merujuk ke semua objek yang dapat dipanggil secara bergantian.
Saya akan mengarahkan Anda ke dua tautan ini untuk detail lebih lanjut:
Fungsi Lambda di C ++ 11: http://www.nullptr.me/2011/10/12/c11-lambda-having-fun-with-brackets/#.UJmXu8XA9Z8
Entitas yang dapat dipanggil di C ++: http://www.nullptr.me/2011/05/31/callable-entity/#.UJmXuMXA9Z8
sumber
std::bind
tidak pernah ada tanpa lambda - kedua fitur tersebut diperkenalkan di C ++ 11. Kami memang memilikibind1st
danbind2nd
yang merupakan versi kurus dari C ++ 11 bind.Saya menggunakannya lama sekali untuk membuat kumpulan utas plugin di C ++; Karena fungsinya mengambil tiga parameter, Anda dapat menulis seperti ini
Misalkan metode Anda memiliki tanda tangan:
Untuk membuat sebuah objek fungsi untuk mengikat ketiga parameter tersebut dapat Anda lakukan seperti ini
Sekarang, untuk mengikat parameter, kita harus menulis fungsi pengikat. Jadi, begini:
Dan, fungsi pembantu untuk menggunakan kelas binder3 - bind3:
dan di sini kami menyebutnya
Catatan: f3 (); akan memanggil metode task1-> ThreeParameterTask (21,22,23);
Untuk detail lebih berdarah -> http://www.codeproject.com/Articles/26078/AC-Plug-in-ThreadPool-Design
sumber