Rumah > pembangunan bahagian belakang > C++ > Mengapa Potongan Jenis Gagal dengan std::function dan Fungsi Lambda dalam C 11?

Mengapa Potongan Jenis Gagal dengan std::function dan Fungsi Lambda dalam C 11?

Mary-Kate Olsen
Lepaskan: 2024-12-20 05:50:10
asal
325 orang telah melayarinya

Why Does Type Deduction Fail with std::function and Lambda Functions in C  11?

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>&amp; input) {
    return input;
}
Salin selepas log masuk

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>&amp; input,function<bool(A)> compare) {
    // ... implementation
}
Salin selepas log masuk

Mencuba memanggil penapis dengan penapis(mySet,[](int i) { return i%2==0; }) ; mengakibatkan ralat:

error: no matching function for call to ‘filter(std::set&amp;, main()::)’
Salin selepas log masuk

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; });
Salin selepas log masuk

Sebagai alternatif, anda boleh mentakrifkan semula fungsi untuk menerima parameter templat untuk CompareFunction:

template<class A,class CompareFunction>
set<A> filter(const set<A>&amp; input,CompareFunction compare) {
    // ... implementation
}
Salin selepas log masuk

Dengan pengubahsuaian ini, anda boleh memanggil fungsi tanpa menyatakan jenis templat:

set<int> result = filter(myIntSet,[](int i) { i % 2 == 0; });
Salin selepas log masuk

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>&amp; input,CompareType compare,IndexType index) -> map<decltype(index(*(input.begin()))),Value> {
    // ... implementation
}
Salin selepas log masuk

Fungsi ini boleh dipanggil seperti berikut:

map<string,int> s = filter(myIntSet,[](int i) { return i%2==0; },[](int i) { return toString(i); });
Salin selepas log masuk

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!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan