'auto' เป็นตัวยึดอาร์กิวเมนต์เทมเพลตสำหรับพารามิเตอร์ฟังก์ชัน


22

C ++ 20 อนุญาตให้ใช้autoสำหรับประเภทพารามิเตอร์ฟังก์ชัน

มันยังอนุญาตให้ใช้autoเป็นตัวยึดอาร์กิวเมนต์เทมเพลต (ไม่เหมือนกัน แต่ในจิตวิญญาณของเทมเพลต C ++ 17 <auto>ในทางใดทางหนึ่ง) สำหรับประเภทพารามิเตอร์ฟังก์ชันหรือไม่

ดังนั้นรหัสต่อไปนี้ก่อน C ++ 20:

template<typename First, typename Second>
void printPair(const std::pair<First, Second>& p) {
    std::cout << p.first << ", " << p.second;
}

สามารถเขียนเป็น:

void printPair(const std::pair<auto, auto>& p) {
    std::cout << p.first << ", " << p.second;
}

มันรวบรวมและทำงานได้ดีกับการใช้ GCC เชิงทดลองสำหรับแนวคิด

มันเป็นไวยากรณ์ที่ถูกต้องกับ C ++ 20 หรือไม่?


จากสิ่งที่ฉันได้ยินไม่มีข้อ จำกัดแปลauto โดยตรงเป็น templatised typename XYZซึ่งจะบ่งบอกว่ามันเป็นไวยากรณ์ที่ถูกต้อง เรียบร้อย
Fureeish

2
โปรดทราบว่าเสียงดังกังวานไม่เห็นด้วยและเสียงดังกราวและ GCC มีความขัดแย้งกันเกี่ยวกับการautoอนุญาตใน[](const std::pair<auto, auto>& p){}(ไม่ว่าจะมี-std=c++2aหรือ-std=c++17)
วอลนัท


ขอบคุณ @DavisHerring - ฉันได้แก้ไขถ้อยคำแล้ว
Amir Kirsh

คำตอบ:


17

ไวยากรณ์นี้ใช้ได้ในข้อกำหนดทางเทคนิคของ C ++ Concepts แต่ไม่อยู่ใน C ++ 20 ในแนวคิด C ++ 20 autoได้รับอนุญาตเฉพาะที่ระดับสูงสุดในประเภทพารามิเตอร์ฟังก์ชัน กฎที่เกี่ยวข้องคือ[dcl.spec.auto] วรรค 2 :

ยึดชนิด-ระบุของรูปแบบประเภท จำกัด [การเลือก] autoสามารถนำมาใช้เป็นdecl-ระบุของdecl-ระบุ-หมายเลขของพารามิเตอร์ประกาศของประกาศฟังก์ชันหรือแลมบ์ดาแสดงออกและถ้ามันไม่ได้เป็นauto type-specifierแนะนำtrailing-return-type (ดูด้านล่าง) เป็นตัวยึดประเภทพารามิเตอร์ทั่วไปของการประกาศฟังก์ชันหรือlambda-expression. [หมายเหตุ: การมีตัวยึดชนิดพารามิเตอร์ทั่วไปหมายความว่าฟังก์ชันนั้นเป็นเทมเพลตฟังก์ชันย่อ (9.3.3.5 [dcl.fct]) หรือแลมบ์ดาเป็นแลมบ์ดาทั่วไป (7.5.5 [expr.prim.lambda]) - บันทึกย่อ]

(หากคุณตรวจสอบข้อความในแบบร่างการทำงานล่าสุด ณ เวลาที่เขียนคุณจะพบกฎที่แตกต่างกันบ้างกฎข้างต้นได้รับการแก้ไขโดยปัญหาหลัก 2447ซึ่งได้รับการโหวตให้เป็น C ++ 20 ฉบับสุดท้ายที่ปราก ประชุมคณะกรรมการเมื่อสัปดาห์ที่แล้ว)

decl-ระบุในฟังก์ชั่นพารามิเตอร์ลำดับเริ่มต้นของคำหลักและชื่อประเภทในช่วงเริ่มต้นของการประกาศพารามิเตอร์ที่ กฎข้างต้นอนุญาตให้autoมีระดับสูงสุด:

void f(auto x);

... แต่เป็นเพียงตัวระบุเดค autoไม่ได้รับอนุญาตเมื่อซ้อนกันภายในdecl-specifier :

void f(std::vector<auto> x);

... และไม่ได้รับอนุญาตจากที่อื่นในประเภทพารามิเตอร์:

void f(void (*p)(auto));

ว้าวฉันไม่รู้สิ! ขณะนี้ลิงก์ CWG ให้ 404 คุณสามารถอธิบายเหตุผลสั้น ๆ เกี่ยวกับข้อ จำกัด นี้ได้หรือไม่?
LF

มันน่าผิดหวังอย่างที่สุด
Fureeish

1
ขออภัยปัญหา CWG และการเปลี่ยนแปลงข้อความยังไม่เปิดเผยต่อสาธารณะ กฎที่เป็นปัญหาถูกนำเสนอโดยopen-std.org/jtc1/sc22/wg21/docs/papers/2018/p1141r2.htmlและเจตนา / เหตุผลนั้นสอดคล้องกับสิ่งที่เราอนุญาตให้ใช้กับลูกแกะทั่วไป
Richard Smith

4
@LF: ปัญหา CWG ไม่เกี่ยวข้องกันจริงๆ: แก้ไขข้อผิดพลาดของถ้อยคำที่บอกเป็นนัยว่าการใช้งานบางอย่างautoสำหรับประเภทการย้อนกลับต่อท้ายซึ่งนับเป็นการautoใช้งานประเภทนี้
Davis Herring
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.