Saya ingin tahu apakah mungkin untuk menulis fungsi yang mengembalikan fungsi lambda di C ++ 11. Tentu satu masalah adalah bagaimana mendeklarasikan fungsi tersebut. Setiap lambda memiliki tipe, tetapi tipe itu tidak dapat diekspresikan dalam C ++. Saya tidak berpikir ini akan berhasil:
auto retFun() -> decltype ([](int x) -> int)
{
return [](int x) { return x; }
}
Juga bukan ini:
int(int) retFun();
Saya tidak mengetahui adanya konversi otomatis dari lambda ke, katakanlah, pointer ke fungsi, atau semacamnya. Apakah satu-satunya solusi membuat objek fungsi dan mengembalikannya?
decltype
tidak sama dengan di badan fungsi dan oleh karena itu memiliki tipe yang berbeda (bahkan jika Anda menyertakan pernyataan return)decltype([](){})
atausizeof([]() {})
tidak berbentuk tidak peduli di mana Anda menulisnya.Jawaban:
Anda tidak memerlukan objek fungsi buatan tangan, cukup gunakan
std::function
, yang fungsi lambda dapat dikonversi:Contoh ini mengembalikan fungsi identitas integer:
std::function<int (int)> retFun() { return [](int x) { return x; }; }
sumber
std::function
.std::function
menggunakan penghapusan tipe, yang berarti biaya untuk membuat panggilan fungsi virtual saat memanggilstd::function
. Sesuatu yang harus diperhatikan jika fungsi yang dikembalikan akan digunakan dalam loop dalam yang ketat atau konteks lain di mana sedikit masalah inefisiensi.Untuk contoh sederhana ini, Anda tidak perlu
std::function
.Dari standar §5.1.2 / 6:
Karena fungsi Anda tidak memiliki tangkapan, itu berarti lambda dapat diubah menjadi penunjuk ke fungsi tipe
int (*)(int)
:typedef int (*identity_t)(int); // works with gcc identity_t retFun() { return [](int x) { return x; }; }
Itu pemahaman saya, koreksi saya jika saya salah.
sumber
Anda bisa mengembalikan fungsi lambda dari fungsi lambda lainnya, karena Anda tidak boleh secara eksplisit menentukan jenis kembalian fungsi lambda. Tulis saja sesuatu seperti itu dalam lingkup global:
auto retFun = []() { return [](int x) {return x;}; };
sumber
Meskipun pertanyaannya secara khusus menanyakan tentang C ++ 11, demi orang lain yang tersandung pada hal ini dan memiliki akses ke kompiler C ++ 14, C ++ 14 sekarang memungkinkan tipe pengembalian yang disimpulkan untuk fungsi biasa. Jadi contoh dalam pertanyaan dapat disesuaikan agar berfungsi seperti yang diinginkan hanya dengan menghapus
-> decltype
klausa ... setelah daftar parameter fungsi:auto retFun() { return [](int x) { return x; } }
Namun, perhatikan bahwa ini tidak akan berfungsi jika lebih dari satu
return <lambda>;
muncul di fungsi. Ini karena batasan pada pengurangan tipe pengembalian adalah bahwa semua pernyataan pengembalian harus mengembalikan ekspresi dari tipe yang sama, tetapi setiap objek lambda diberikan tipe uniknya sendiri oleh kompilator, sehinggareturn <lambda>;
ekspresi masing-masing akan memiliki tipe yang berbeda.sumber
auto retFun() { return [](auto const& x) { return x; }; }
Anda harus menulis seperti ini:
auto returnFunction = [](int x){ return [&x](){ return x; }(); };
untuk mendapatkan hasil Anda sebagai fungsi, dan menggunakannya seperti:
int val = returnFunction(someNumber);
sumber
Jika Anda tidak memiliki c ++ 11 dan menjalankan kode c ++ pada pengontrol mikro misalnya. Anda dapat mengembalikan penunjuk kosong dan kemudian melakukan cast.
void* functionThatReturnsLambda() { void(*someMethod)(); // your lambda someMethod = []() { // code of lambda }; return someMethod; } int main(int argc, char* argv[]) { void* myLambdaRaw = functionThatReturnsLambda(); // cast it auto myLambda = (void(*)())myLambdaRaw; // execute lambda myLambda(); }
sumber