'otomatis' sebagai placeholder argumen templat untuk parameter fungsi

22

C ++ 20 memungkinkan penggunaan autountuk tipe parameter fungsi.

Apakah itu juga memungkinkan penggunaan autosebagai placeholder argumen templat (tidak serupa, tetapi dalam semangat C ++ 17 templat <auto> dengan cara) untuk tipe parameter fungsi?

Jadi kode berikut, pra C ++ 20:

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

Dapat ditulis sebagai:

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

Itu mengkompilasi dan bekerja dengan baik dengan implementasi GCC eksperimental untuk konsep.

Apakah ini sintaks yang sah dengan C ++ 20?

Amir Kirsh
sumber
Dari apa yang saya dengar, tidak dibatasi auto langsung diterjemahkan menjadi templatised typename XYZ, yang akan sangat menyiratkan bahwa itu adalah sintaks yang sah. Rapi .
Fureeish
2
Perhatikan bahwa Dentang tidak setuju dan bahwa Dentang dan GCC memiliki ketidaksepakatan yang sama tentang apakah autodiperbolehkan [](const std::pair<auto, auto>& p){}(apakah dengan -std=c++2aatau -std=c++17).
kenari
Terima kasih @visviser - Saya telah memperbaiki kata-katanya
Amir Kirsh

Jawaban:

17

Sintaks ini valid dalam Spesifikasi Teknis Konsep C ++, tetapi tidak dalam C ++ 20. Dalam konsep C ++ 20, autohanya diizinkan di tingkat atas dalam tipe parameter fungsi. Aturan yang relevan adalah [dcl.spec.auto] paragraf 2 :

Sebuah placeholder-tipe-specifier dari bentuk jenis-kendala [opt] autodapat digunakan sebagai decl-specifier dari decl-specifier-seq dari parameter-deklarasi dari deklarasi fungsi atau lambda ekspresi dan, jika itu bukan auto type-specifier memperkenalkan tipe trailing-return-type (lihat di bawah), adalah placeholder tipe parameter generik dari deklarasi fungsi atau ekspresi lambda. [Catatan: Memiliki placeholder jenis parameter generik menandakan bahwa fungsi tersebut merupakan templat fungsi disingkat (9.3.3.5 [dcl.fct]) atau lambda adalah lambda generik (7.5.5 [expr.prim.lambda]). —Kirim catatan]

(Jika Anda memeriksa kata-kata dalam draft kerja terbaru pada saat penulisan, Anda akan menemukan aturan yang agak berbeda. Aturan di atas telah dimodifikasi oleh isu inti 2447 , yang terpilih ke dalam draft akhir C ++ 20 di Praha rapat komite seminggu yang lalu.)

The decl-specifier s dalam fungsi parameter adalah urutan awal kata kunci dan nama jenis pada awal deklarasi parameter. Aturan di atas memungkinkan autoada di tingkat atas:

void f(auto x);

... tetapi hanya sebagai penentu-pernyataan . autotidak diizinkan ketika bersarang di dalam specifier-pernyataan :

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

... dan juga tidak diizinkan di tempat lain dalam tipe parameter:

void f(void (*p)(auto));
Richard Smith
sumber
Wow, saya tidak tahu itu! Tautan CWG saat ini memberikan 404, jadi dapatkah Anda menjelaskan secara singkat alasan pembatasan ini?
LF
Ini benar-benar mengecewakan.
Fureeish
1
Maaf, masalah CWG dan perubahan kata-katanya belum terlihat oleh publik. Aturan tersebut diperkenalkan oleh open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1141r2.html dan maksud / alasannya adalah konsisten dengan apa yang telah kami izinkan untuk lambda generik.
Richard Smith
4
@ LF: Masalah CWG sebenarnya tidak benar-benar relevan: itu memperbaiki kesalahan kata yang menyiratkan bahwa penggunaan tertentu autountuk tipe trailing return dihitung sebagai jenis autopenggunaan ini.
Davis Herring