ส่งคืนชนิดการส่งต่อในรหัสทั่วไป
สำหรับโค้ดที่ไม่ใช่รหัสทั่วไปเช่นตัวอย่างเริ่มต้นที่คุณให้คุณสามารถเลือกด้วยตนเองเพื่อรับการอ้างอิงเป็นประเภทส่งคืน:
auto const& Example(int const& i)
{
return i;
}
แต่ในรหัสทั่วไปคุณต้องการส่งต่อชนิดส่งคืนได้อย่างสมบูรณ์โดยไม่ทราบว่าคุณกำลังติดต่อกับการอ้างอิงหรือค่า decltype(auto)
ให้ความสามารถนั้นแก่คุณ:
template<class Fun, class... Args>
decltype(auto) Example(Fun fun, Args&&... args)
{
return fun(std::forward<Args>(args)...);
}
การหน่วงเวลาการหักชนิดส่งคืนในเท็มเพลตแบบเรียกซ้ำ
ในนี้ Q & Aไม่กี่วันที่ผ่านมามีการเรียกซ้ำอนันต์ระหว่างแม่แบบ instantiation ถูกพบเมื่อประเภทการกลับมาของแม่แบบที่ถูกระบุเป็นแทนdecltype(iter(Int<i-1>{}))
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)
ใช้ที่นี่เพื่อชะลอการหักค่าส่งคืนหลังจากฝุ่นของแม่แบบอินสแตนซ์ได้ตัดสิน
การใช้งานอื่น ๆ
นอกจากนี้คุณยังสามารถใช้decltype(auto)
ในบริบทอื่น ๆ เช่นร่างมาตรฐานN3936ยังรัฐ
7.1.6.4 ข้อมูลจำเพาะอัตโนมัติ [dcl.spec.auto]
1 ตัวระบุประเภทauto
และdecltype(auto)
กำหนดประเภทตัวยึดที่จะถูกแทนที่ในภายหลังโดยการหักจาก initializer หรือโดยการระบุอย่างชัดเจนด้วย trailing-return-type auto
Fi เอ้อชนิด speci ยังใช้เพื่อหมายว่าแลมบ์ดาเป็นแลมบ์ดาทั่วไป
2 ประเภทตัวยึดสามารถปรากฏกับ declarator ฟังก์ชั่นใน decl-ระบุ-seq, ชนิดระบุ-seq แปลงฟังก์ชั่น-ID หรือต่อท้ายผลตอบแทนชนิดในบริบทใด ๆ ที่เช่น declarator เป็นที่ถูกต้อง ถ้าฟังก์ชั่น declarator รวมถึง trailing-return-type (8.3.5) นั่นจะระบุประเภทการส่งคืนที่ประกาศของฟังก์ชัน หากชนิดส่งคืนที่ประกาศของฟังก์ชันมีประเภทตัวยึดตำแหน่งประเภทส่งคืนของฟังก์ชันจะถูกหักจากคำสั่งส่งคืนในเนื้อหาของฟังก์ชันหากมี
แบบร่างยังมีตัวอย่างของการกำหนดค่าเริ่มต้นตัวแปรนี้:
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)