บทนำ
constexpr
ไม่ได้ถูกนำมาใช้เป็นวิธีที่จะบอกการดำเนินการว่าบางสิ่งสามารถประเมินได้ในบริบทที่ต้องมีการแสดงออกอย่างต่อเนื่อง ; การใช้งานที่สอดคล้องกันสามารถพิสูจน์สิ่งนี้ได้ก่อน C ++ 11
สิ่งที่การนำไปปฏิบัติไม่สามารถพิสูจน์ได้คือเจตนาของรหัสบางส่วน:
- มันคืออะไรที่นักพัฒนาต้องการที่จะแสดงกับเอนทิตีนี้?
- เราควรอนุญาตให้ใช้รหัสในการแสดงออกอย่างต่อเนื่องแบบสุ่มสี่สุ่มห้าเพียงเพราะมันเกิดขึ้นในการทำงานหรือไม่
โลกจะปราศจากconstexpr
อะไร
สมมติว่าคุณกำลังพัฒนาไลบรารีและตระหนักว่าคุณต้องการคำนวณผลรวมของจำนวนเต็มทุกตัวในช่วงเวลา(0,N]
นั้น
int f (int n) {
return n > 0 ? n + f (n-1) : n;
}
การขาดความตั้งใจ
คอมไพเลอร์สามารถพิสูจน์ได้อย่างง่ายดายว่าฟังก์ชั่นด้านบนสามารถเรียกใช้ในการแสดงออกคงที่ถ้าการโต้แย้งผ่านเป็นที่รู้จักในระหว่างการแปล; แต่คุณไม่ได้ประกาศว่านี่เป็นเจตนา - มันเพิ่งจะเกิดขึ้น
ตอนนี้มีคนอื่นมาอ่านฟังก์ชั่นของคุณทำการวิเคราะห์เช่นเดียวกับคอมไพเลอร์ " โอ้ฟังก์ชั่นนี้สามารถใช้งานได้อย่างต่อเนื่อง!" และเขียนรหัสต่อไปนี้
T arr[f(10)]; // freakin' magic
การเพิ่มประสิทธิภาพ
คุณเป็น"น่ากลัว"นักพัฒนาห้องสมุดตัดสินใจว่าf
ควรแคชผลเมื่อมีการเรียก; ใครจะต้องการคำนวณค่าชุดเดียวกันซ้ำไปซ้ำมา
int func (int n) {
static std::map<int, int> _cached;
if (_cached.find (n) == _cached.end ())
_cached[n] = n > 0 ? n + func (n-1) : n;
return _cached[n];
}
ผลลัพธ์
ด้วยการแนะนำการเพิ่มประสิทธิภาพที่โง่เง่าของคุณคุณเพียงแค่ทำลายการใช้งานฟังก์ชันของคุณทุกครั้งที่เกิดขึ้นในบริบทที่จำเป็นต้องมีการแสดงออกอย่างต่อเนื่อง
คุณไม่เคยสัญญาว่าฟังก์ชั่นนั้นสามารถใช้งานได้อย่างต่อเนื่องและถ้าไม่มีconstexpr
ก็จะไม่มีวิธีให้สัญญาเช่นนั้น
ดังนั้นทำไมเราต้องconstexpr
?
การใช้งานหลักของconstexprคือการประกาศเจตนา
หากเอนทิตีไม่ได้ถูกทำเครื่องหมายว่าเป็นconstexpr
- มันไม่เคยตั้งใจที่จะใช้ในการแสดงออกคงที่ ; และแม้ว่าจะเป็นไปได้ก็ตามเราพึ่งพาคอมไพเลอร์เพื่อวิเคราะห์บริบทดังกล่าว (เพราะไม่สนใจเจตนาของเรา)
constexpr
หรือไม่? ถ้าเป็นเช่นนั้นฉันสามารถเห็นการใช้งาน