Kembalikan jenis penerusan dalam kode generik
Untuk kode non-generik, seperti contoh awal yang Anda berikan, Anda dapat memilih secara manual untuk mendapatkan referensi sebagai tipe pengembalian:
auto const& Example(int const& i)
{
return i;
}
tetapi dalam kode generik Anda ingin dapat meneruskan tipe pengembalian dengan sempurna tanpa mengetahui apakah Anda berurusan dengan referensi atau nilai. decltype(auto)
memberi Anda kemampuan itu:
template<class Fun, class... Args>
decltype(auto) Example(Fun fun, Args&&... args)
{
return fun(std::forward<Args>(args)...);
}
Menunda pengurangan jenis pengembalian dalam templat rekursif
Dalam Tanya Jawab ini beberapa hari yang lalu, rekursi tak terbatas selama instantiasi templat ditemukan ketika jenis pengembalian templat ditentukan sebagai decltype(iter(Int<i-1>{}))
ganti decltype(auto)
.
template<int i>
struct Int {};
constexpr auto iter(Int<0>) -> Int<0>;
template<int i>
constexpr auto iter(Int<i>) -> decltype(auto)
{ return iter(Int<i-1>{}); }
int main() { decltype(iter(Int<10>{})) a; }
decltype(auto)
digunakan di sini untuk menunda pengurangan tipe pengembalian setelah debu instantiation template telah menetap.
Penggunaan lainnya
Anda juga dapat menggunakan decltype(auto)
dalam konteks lain, misalnya konsep Standar N3936 juga menyatakan
7.1.6.4 penentu otomatis [dcl.spec.auto]
1 auto
dan decltype(auto)
penspesifikasi tipe menunjuk tipe placeholder yang akan diganti nanti, baik dengan deduksi dari inisialisasi atau dengan spesi fi kasi eksplisit dengan tipe trailing-return-type. The auto
tipe-spesifik er juga digunakan untuk menandakan bahwa lambda adalah lambda generik.
2 Tipe placeholder dapat muncul dengan deklarator fungsi di menyatakan-specifier-seq, tipe-specifier-seq, konversi-fungsi-id, atau tipe trailing-return, dalam konteks apa pun di mana deklarator tersebut valid . Jika deklarator fungsi menyertakan tipe trailing-return-tipe (8.3.5), yang menentukan tipe pengembalian yang dinyatakan dari fungsi. Jika tipe pengembalian yang dideklarasikan dari fungsi berisi tipe placeholder, tipe kembali dari fungsi tersebut disimpulkan dari pernyataan pengembalian dalam tubuh fungsi, jika ada.
Draf ini juga berisi contoh inisialisasi variabel ini:
int i;
int&& f();
auto x3a = i; // decltype(x3a) is int
decltype(auto) x3d = i; // decltype(x3d) is int
auto x4a = (i); // decltype(x4a) is int
decltype(auto) x4d = (i); // decltype(x4d) is int&
auto x5a = f(); // decltype(x5a) is int
decltype(auto) x5d = f(); // decltype(x5d) is int&&
auto x6a = { 1, 2 }; // decltype(x6a) is std::initializer_list<int>
decltype(auto) x6d = { 1, 2 }; // error, { 1, 2 } is not an expression
auto *x7a = &i; // decltype(x7a) is int*
decltype(auto)*x7d = &i; // error, declared type is not plain decltype(auto)