c++ - يمكن تمرير القيم Lambda إغلاق كمعلمات مرجع rvalue




closures c++14 (2)

كيف ولماذا تعمل الحالة 1؟

يتطلب استدعاء foo مثيل std::function<void()> يرتبط بمرجع rvalue . std::function<void()> من أي كائن قابل للاتصال متوافق مع توقيع void() .

أولاً ، يتم إنشاء كائن مؤقت std::function<void()> من []{} . المُنشئ المستخدم هو # 5 here ، الذي ينسخ الإغلاق في مثيل std::function :

template< class F >
function( F f );

تهيئة الهدف باستخدام std::move(f) . إذا كانت f عبارة عن مؤشر لاغٍ عن العمل أو مؤشر لاغٍ إلى عضو ، فسيكون *this فارغًا بعد المكالمة.

بعد ذلك ، يرتبط مثيل function المؤقتة بمرجع rvalue.

ما هي حالة إغلاق fn1 بعد إرجاع الوظيفة؟

كما كان من قبل ، لأنه تم نسخه في نسخة std::function . إغلاق الأصلي يتأثر.

لقد وجدت أن إغلاق rvalue lambda يمكن دائمًا تمريره rvalue دالة rvalue .

انظر مظاهرة بسيطة التالية.

#include <iostream>
#include <functional>

using namespace std;

void foo(std::function<void()>&& t)
{
}

int main()
{
    // Case 1: passing a `lvalue` closure
    auto fn1 = []{};
    foo(fn1);                          // works

    // Case 2: passing a `lvalue` function object
    std::function<void()> fn2 = []{};
    foo(fn2);                          // compile error

    return 0;
}

الحالة 2 هي السلوك القياسي (لقد استخدمت std::function لأغراض العرض التوضيحي ، ولكن أي نوع آخر سيتصرف بنفس الطريقة).

كيف ولماذا تعمل الحالة 1؟ ما هي حالة إغلاق fn1 بعد إرجاع الوظيفة؟


ما هي حالة إغلاق fn1 بعد إرجاع الوظيفة؟

fn1 هو عديمي الجنسية ، لأنه لا يجسد شيئًا.

كيف ولماذا تعمل الحالة 1؟

إنه يعمل لأن الوسيطة من نوع مختلف عن النوع الذي يشير إليه rvalue. نظرًا لوجود نوع مختلف ، يتم اعتبار التحويلات الضمنية. نظرًا لأن lambda هو Callable من أجل وسيطات هذه std::function ، فإنه يمكن تحويلها ضمنيًا من خلال مُنشئ تحويل القالب std::function . نتيجة التحويل هي قيمة ، وبالتالي يمكن ربطها بمرجع القيمة.





rvalue-reference