Auto และ Decltype มีจุดประสงค์ที่แตกต่างกัน ดังนั้นจึงไม่จับคู่แบบหนึ่งต่อหนึ่ง auto เป็นคีย์เวิร์ดใน C++11 และใหม่กว่าที่ใช้สำหรับการหักประเภทอัตโนมัติ ตัวระบุประเภท Decltype ให้ประเภทของนิพจน์ที่ระบุ ไม่เหมือนกับ auto ที่อนุมานประเภทตามค่าที่กำหนดให้กับตัวแปร decltype อนุมานประเภทจากนิพจน์ที่ส่งผ่านไปยังตัวแปรนั้น ค่าที่ส่งคืนโดย decltype สามารถใช้กำหนดตัวแปรอื่นได้โดยตรง
auto ปฏิบัติตามกฎของการหักพารามิเตอร์เทมเพลต คุณสามารถอ่านเพิ่มเติมเกี่ยวกับกฎเหล่านี้ได้ที่ https://en.cppreference.com/w/cpp/language/template_argument_deduction
ในขณะที่ decltype มีกฎ แต่ก็ควรเป็นไปตามที่กำหนดไว้ในมาตรฐาน นี่คือข้อความที่ตัดตอนมาจากมาตรฐานของกฎเหล่านี้:
ในทำนองเดียวกันกับตัวดำเนินการ sizeof ตัวถูกดำเนินการของ decltype นั้นไม่มีการประเมิน อย่างไม่เป็นทางการ ประเภทที่ส่งคืนโดย decltype(e) ถูกอนุมานได้ดังนี้ -
- หากนิพจน์ e หมายถึงตัวแปรในขอบเขตโลคัลหรือเนมสเปซ ตัวแปรสมาชิกสแตติก หรือพารามิเตอร์ฟังก์ชัน ผลลัพธ์ก็คือประเภทประกาศของตัวแปรหรือพารามิเตอร์นั้น
- หาก e เป็นการเรียกใช้ฟังก์ชันหรือการเรียกใช้ตัวดำเนินการโอเวอร์โหลด decltype(e) จะระบุประเภทการส่งคืนที่ประกาศของฟังก์ชันนั้น
- มิฉะนั้น ถ้า e เป็นค่า lvalue, decltype(e) คือ T&โดยที่ T คือประเภทของ e; ถ้า e เป็นค่า rvalue ผลลัพธ์จะเป็น T
ความหมายเหล่านี้ได้รับการออกแบบมาเพื่อตอบสนองความต้องการของผู้เขียนไลบรารีทั่วไป ในขณะเดียวกันก็ใช้งานได้ง่ายสำหรับโปรแกรมเมอร์มือใหม่ เนื่องจากประเภทการส่งคืนของ decltype จะตรงกับประเภทของอ็อบเจ็กต์หรือฟังก์ชันตรงตามที่ประกาศไว้ใน รหัสแหล่งที่มา. เป็นทางการมากขึ้น กฎข้อที่ 1 ใช้กับนิพจน์รหัสที่ไม่อยู่ในวงเล็บและนิพจน์การเข้าถึงของสมาชิกคลาส สำหรับการเรียกใช้ฟังก์ชัน ประเภทอนุมานเป็นประเภทส่งคืนของฟังก์ชันที่เลือกแบบสแตติก ตามที่กำหนดโดยกฎสำหรับความละเอียดโอเวอร์โหลด
ตัวอย่าง
ตัวอย่างการใช้ auto และ Decltype
#include<iostream> #include<vector> using namespace std; int main() { // Using auto for type deduction vector<int> arr(10); for(auto it = arr.begin(); it != arr.end(); it ++) { cin >> *it; } // Using decltype for type deduction vector<int> arr(10); for (decltype(arr.begin()) it = arr.begin(); it != arr.end(); it++) { cin >> *it; } return 0; }
โปรดทราบว่าประเภทที่แสดงโดย decltype อาจแตกต่างจากประเภทที่อนุมานโดยอัตโนมัติ คุณสามารถอ่านเพิ่มเติมเกี่ยวกับความแตกต่างที่ลึกซึ้งเหล่านี้ได้ในคำอธิบาย 12 หน้านี้เกี่ยวกับการหักประเภทใน C++ - https://thbecker.net/articles/auto_and_decltype/section_01.html