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
Mary-Kate Olsenasal
2024-12-20 05:50:10327semak imbas

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;
}

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
}

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()::)’

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>&amp; 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>&amp; 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!

Kenyataan:
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