แลมบ์ดาที่ไม่มีการรับประกันรับประกันว่าจะว่างเปล่าตามมาตรฐานหรือไม่?


12

ฉันกำลังค้นหาวิธีที่จะระบุ lambdas ที่ว่างเปล่า (ไม่มีขอบเขต) จาก lambdas อื่น ๆ ในฟังก์ชั่นเทมเพลต ปัจจุบันฉันใช้ C ++ 17 แต่ฉันอยากรู้คำตอบ C ++ 20 ด้วย

รหัสของฉันมีลักษณะเช่นนี้:

template<typename T>
auto func(T lambda) {
    // The aguments of the lambdas are unknown

    if constexpr (/* is captureless */) {
        // do stuff
    }
}

มันรับประกันโดยมาตรฐาน C ++ (17 หรือ 20) ที่แลมบ์ดาที่ไม่มีตัวแปลงซึ่งแปลงสภาพเป็นตัวชี้ฟังก์ชั่นจะทำให้ได้std::is_emptyผลจริงหรือไม่?

ใช้รหัสนี้เป็นตัวอย่าง:

auto a = []{}; // captureless
auto b = [c = 'z']{}; // has captures

static_assert(sizeof(a) == sizeof(b)); // Both are the same size
static_assert(!std::is_empty_v<decltype(b)>); // It has a `c` member
static_assert(std::is_empty_v<decltype(a)>); // Passes. It is guaranteed?

ตัวอย่างสด


2
หากคุณสนใจเฉพาะลูกแกะที่ไม่ใช่เทมเพลตคุณสามารถใช้ SFINAE เพื่อตรวจสอบว่าการแปลงเป็นตัวชี้ฟังก์ชัน ( +lambda) นั้นมีรูปแบบที่ดีหรือไม่
HolyBlackCat

@HolyBlackCat ฉันคิดเกี่ยวกับเรื่องนั้น แต่เท่าที่ฉันจำได้ MSVC ไม่อนุญาตเพราะพวกเขาโอเวอร์โหลดตัวดำเนินการแปลง
Guillaume Racicot

@GuillaumeRacicot MS แสดงตัวดำเนินการแปลงแยกต่างหากสำหรับอนุสัญญาการโทรที่มีอยู่ทั้งหมด เพียงเลือกหนึ่งตัวและลองแปลงแลมบ์ดาไปเป็นตัวชี้ฟังก์ชั่นที่เปรียบเทียบได้และตรวจสอบว่าสำเร็จหรือล้มเหลว
Remy Lebeau

+ดูเหมือนว่าจะทำงานที่นี่
HolyBlackCat

คำตอบ:


13

ไม่จริงมาตรฐานได้รับอนุญาตอย่างชัดเจนสำหรับลูกแกะที่มีขนาดที่ไม่สอดคล้องกับคำประกาศของพวกเขา [expr.prim.lambda.closure] / 2สถานะ

ประเภทการปิดถูกประกาศในขอบเขตบล็อกที่เล็กที่สุดขอบเขตคลาสหรือขอบเขตเนมสเปซที่มีการแสดงออกแลมบ์ดาที่สอดคล้องกัน [หมายเหตุ: นี่เป็นการกำหนดชุดของเนมสเปซและคลาสที่สัมพันธ์กับชนิดการปิด ([basic.lookup.argdep]) ชนิดพารามิเตอร์ของ lambda-declarator ไม่มีผลกับเนมสเปซและคลาสที่เชื่อมโยงเหล่านี้ - หมายเหตุท้าย] ประเภทการปิดไม่ใช่ประเภทรวม การนำไปใช้อาจกำหนดประเภทการปิดแตกต่างจากที่อธิบายไว้ด้านล่างหากไม่ได้เปลี่ยนแปลงพฤติกรรมที่สังเกตได้ของโปรแกรมอื่นนอกเหนือจากการเปลี่ยนแปลง:

  • ขนาดและ / หรือการจัดตำแหน่งของประเภทปิด

  • ไม่ว่าประเภทการปิดสามารถคัดลอกได้เล็กน้อย ([class.prop]) หรือ (2.3)

  • ประเภทการปิดเป็นคลาสเลย์เอาต์มาตรฐาน ([class.prop])

การดำเนินการจะต้องไม่เพิ่มสมาชิกประเภทการอ้างอิงค่าลงในประเภทการปิด

ฉันเน้น

ดังนั้นสิ่งนี้จะช่วยให้การดำเนินการเพื่อให้แลมบ์ดาเป็นสมาชิกแม้ว่าจะไม่ถูกจับกุมก็ตาม ฉันไม่คิดว่าจะมีการดำเนินการใด ๆ แต่จะได้รับอนุญาตตามกฎหมายให้ทำเช่นนั้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.