Jenis Potongan dengan std::function dan Fungsi Lambda dalam C 11
Apabila bekerja dengan templat dalam C 11, jenis potongan boleh menjadi ciri yang berkuasa. Walau bagaimanapun, terdapat senario tertentu di mana potongan jenis gagal, khususnya apabila fungsi std::function atau lambda terlibat.
Dalam contoh berikut, ujian fungsi menerima set jenis A dan mengembalikan set yang sama tanpa secara eksplisit. menyatakan jenis templat:
template<class A> set<A> test(const set<A>& input) { return input; }
Memanggil fungsi ini dengan test(mySet) di tempat lain dalam kod berfungsi seperti yang diharapkan. Walau bagaimanapun, apabila menggunakan fungsi dengan fungsi lambda, potongan jenis gagal:
template<class A> set<A> filter(const set<A>& input,function<bool(A)> compare) { // ... implementation }
Mencuba memanggil penapis dengan penapis(mySet,[](int i) { return i%2==0; }) ; mengakibatkan ralat:
error: no matching function for call to ‘filter(std::set&, main()::)’
Isu ini timbul kerana lambdas bukan fungsi atau objek std::function. Ia adalah objek fungsi dengan sifat khusus yang ditakrifkan oleh standard. Potongan jenis hanya berfungsi dengan jenis yang tepat dan lambda tidak memenuhi kriteria ini.
Untuk menyelesaikan masalah ini, anda boleh menukar lambda kepada fungsi std:: atau menyediakan jenis templat secara eksplisit:
// Convert lambda to std::function std::function<bool(int)> func = [](int i) { return i%2 ==0; }; set<int> myNewSet = filter(mySet,func); // Provide template type explicitly set<int> myNewSet = filter<int>(mySet,[](int i) { return i%2==0; });
Sebagai alternatif, anda boleh mentakrifkan semula fungsi untuk menerima parameter templat untuk CompareFunction:
template<class A,class CompareFunction> set<A> filter(const set<A>& input,CompareFunction compare) { // ... implementation }
Dengan pengubahsuaian ini, anda boleh memanggil fungsi tanpa menyatakan jenis templat:
set<int> result = filter(myIntSet,[](int i) { i % 2 == 0; });
Potongan jenis juga boleh menjadi masalah dengan lambda berbilang hujah. Dalam kes sedemikian, menggunakan auto boleh menjadi penyelesaian yang berguna:
template<class Value,class CompareType,class IndexType> auto filter(const set<Value>& input,CompareType compare,IndexType index) -> map<decltype(index(*(input.begin()))),Value> { // ... implementation }
Fungsi ini boleh dipanggil seperti berikut:
map<string,int> s = filter(myIntSet,[](int i) { return i%2==0; },[](int i) { return toString(i); });
Atas ialah kandungan terperinci Mengapa Potongan Jenis Gagal dengan std::function dan Fungsi Lambda dalam C 11?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!