operator panah (->) di judul fungsi

128

Saya menemukan kode berikut:

template <typename T, typename T1> auto compose(T a, T1 b) -> decltype(a + b) {
   return a+b;
}

Ada satu hal yang tidak dapat saya mengerti:

Di mana saya bisa mengetahui apa yang dimaksud dengan operator panah ( ->) dalam heading fungsi? Saya kira secara logis, bahwa ->operator menentukan jenis, yang autoakan disimpulkan, tetapi saya ingin menjelaskannya secara langsung. Saya tidak dapat menemukan informasi apa pun.

pengguna1234567
sumber
2
Ini adalah bagian dari sintaks tipe hasil akhir. Lihat stackoverflow.com/a/4113390/962089
chris
2
Ini bukan operator tetapi bagian dari sintaks.
texasbruce
1
Dalam menjawab "di mana saya bisa membaca?", C ++ Spec adalah yang paling otoritatif. Karena kekurangan dana atau keinginan untuk membelanjakan $$, draf kerja terakhir seringkali cukup dekat dan tanpa biaya. Spesifikasi ini sangat techo-speak, jadi kurang familiar dengan membaca spesifikasi ISO, coba cplusplus.com atau cppreference.com atau situs serupa lainnya yang tidak otoritatif, tetapi biasanya sangat akurat. Catatan: tipe hasil akhir dapat dihilangkan dimulai dengan C ++ 14.
Les

Jawaban:

205

Di C ++ 11, ada dua sintaks untuk deklarasi fungsi:

     deklarasi-argumen pengenal tipe-balik ( ... )

dan

    auto pengenal ( argumen-deklarasi ... ) -> return_type

Mereka setara. Sekarang jika mereka setara, mengapa Anda ingin menggunakan yang terakhir? Nah, C ++ 11 memperkenalkan hal keren ini decltypeyang memungkinkan Anda mendeskripsikan tipe ekspresi. Jadi Anda mungkin ingin mendapatkan tipe kembalian dari tipe argumen. Jadi Anda mencoba:

template <typename T1, typename T2>
decltype(a + b) compose(T1 a, T2 b);

dan kompilator akan memberi tahu Anda bahwa ia tidak tahu apa adan yang bada di dalam decltypeargumen. Itu karena mereka hanya dideklarasikan oleh daftar argumen.

Anda dapat dengan mudah mengatasi masalah dengan menggunakan declvaldan parameter template yang telah dideklarasikan. Suka:

template <typename T1, typename T2>
decltype(std::declval<T1>() + std::declval<T2>())
compose(T1 a, T2 b);

kecuali itu menjadi sangat bertele-tele sekarang. Jadi sintaks deklarasi alternatif telah diusulkan dan diimplementasikan dan sekarang Anda dapat menulis

template <typename T1, typename T2>
auto compose(T1 a, T2 b) -> decltype(a + b);

dan tidak terlalu bertele-tele dan aturan pelingkupan tidak perlu diubah.


Pembaruan C ++ 14: C ++ 14 juga mengizinkan

    auto pengenal ( argumen-deklarasi ... )

selama fungsinya didefinisikan sepenuhnya sebelum digunakan dan semua returnpernyataan menyimpulkan jenis yang sama. The ->sintaks tetap berguna untuk fungsi publik (dideklarasikan di header) jika Anda ingin menyembunyikan tubuh dalam file sumber. Agak jelas itu tidak dapat dilakukan dengan templat, tetapi ada beberapa jenis konkret (biasanya diturunkan melalui metaprogramming templat) yang sulit untuk ditulis sebaliknya.

Jan Hudec
sumber
2
sangat bagus, rapi dan informatif balas @Jan Hudec. Thumps up. Apakah ada sesuatu yang berubah C++14saat saya gunakan autountuk returnmengetikkan fungsi seperti itu tanpa memerlukan -> decltype(a + b)bagian tersebut. Apakah sekarang sudah mubazir atau ada kasus lain yang masih harus digunakan? atau apakah itu ekstensi khusus kompilator?
Shadi
1
@Shadi, C ++ 14 menyertakan N3638 , yang memungkinkan pengurangan jenis kembalian yang dideklarasikan sebagai auto, tanpa ->notasi, selama fungsi tersebut sepenuhnya ditentukan sebelum digunakan dan semua returnpernyataan menyimpulkan ke jenis yang sama. The ->notasi masih berguna jika Anda ingin menggunakan deduksi untuk fungsi publik sementara bersembunyi tubuh dalam file sumber.
Jan Hudec
23

Dalam bahasa Inggris sederhana dikatakan bahwa tipe yang dikembalikan adalah tipe yang disimpulkan dari jumlah adan b.

murrekatt
sumber