Bagaimana std :: is_function diimplementasikan?

82

Bagaimana implementasi berikut ini std::is_function?

template<class T>
struct is_function : std::integral_constant<
    bool,
    !std::is_const<const T>::value && !std::is_reference<T>::value
> {};

(dari Referensi CPP )

Menurut saya, sebuah intakan menjadi fungsi di bawah definisi ini. Apa yang saya lewatkan?

Rian Quinn
sumber
10
Pikirkan !is_constbagian itu.
aschepler
Mengapa tipe fungsi tidak dapat menjadi const? Apakah ini terkait dengan tipe yang menjijikkan?
jtbandes
4
@ jtbandes itu karena fungsi adalah salah satu dari beberapa hal di C ++ yang bukan objek.
Ayxan
1
Saya kira karena dalam arti selalu const
RiaD
Saya merasa judul itu menyesatkan. "Bagaimana ini implementasi std :: is_function yang valid?" sepertinya lebih tepat.
val mengatakan Reinstate Monica

Jawaban:

73

Mari kita melihat kondisi yang muncul:
Jika const Ttidak const ( consttidak benar-benar berlaku untuk jenis fungsi karena fungsi bukan objek), dan Tbukan referensi ( consttidak berlaku untuk referensi baik karena alasan yang sama) , ini adalah tipe fungsi. int(atau tipe non-fungsi-non-referensi lainnya) tidak akan cocok karena is_const<const int>::valuebegitu true.

Menurut C ++ 17 Standar §11.3.5 Fungsi / bagian 7 : (Penekanan tambang)

Efek dari cv-kualifikasi-seq dalam deklarator fungsi tidak sama dengan menambahkan cv-kualifikasi di atas jenis fungsi. Dalam kasus terakhir, kualifikasi cv diabaikan. [ Catatan: Jenis fungsi yang memiliki cv-kualifikasi-seq bukan jenis yang memenuhi syarat cv; tidak ada tipe fungsi yang memenuhi syarat cv. - catatan akhir] [...]

Ayxan
sumber
5
Ah .... Saya kehilangan "const" di dalam bagian is_const ini. Itu masuk akal.
Rian Quinn
54

Hanya ada dua kategori tipe dalam bahasa yang tidak bisa memiliki kualifikasi-kualifikasi: tipe referensi, dan tipe fungsi. Jadi, jika const Tgagal menjadi tipe const-kualifikasi, artinya Tadalah tipe fungsi atau tipe referensi. Jika Anda dapat mengesampingkan tipe referensi, maka Anda hanya memiliki tipe fungsi.

Perhatikan bahwa tipe fungsi yang membawa cv-kualifikasi, seperti int(int) const, bukan tipe const-kualifikasi. Ini adalah contoh dari "tipe fungsi menjijikkan", yang hanya menggunakan nyata untuk membuat atau mendekomposisi tipe fungsi pointer-ke-anggota. Jenis int(int) constini tidak dapat diperoleh dengan menambahkan const-kualifikasi di atas int(int). Sebaliknya, constberlaku untuk parameter objek tersirat.

Brian
sumber