กลับไปหน้าบทความ

อ่าน 15 นาที

คอนเท็กซ์พอาร์

constexpr เป็นคำหลักระบุใน ภาษาการเขียนโปรแกรม C และ C++ ซึ่งโดยคร่าวๆ แล้วระบุว่าบางสิ่งอาจถูกประเมินใน เวลาคอมไพล์ [ 1 ] แตก ต่างจาก const...

คอนเท็กซ์พอาร์

constexprเป็นคำหลักระบุใน ภาษาการเขียนโปรแกรม Cและ C++ซึ่งโดยคร่าวๆ แล้วระบุว่าบางสิ่งอาจถูกประเมินในเวลาคอมไพล์ [ 1 ] แตก ต่างจาก constทั่วไปซึ่งระบุการเข้าถึงแบบอ่านอย่างเดียว constexprเป็นรูปแบบที่แข็งแกร่งกว่าซึ่งบ่งบอก(ในบริบทส่วนใหญ่) ในขณะที่ใน C นั้นจำกัดเฉพาะวัตถุ [ 2 ]อาจใช้กับวัตถุ ฟังก์ชัน หรือการผูกโครงสร้างใน C++ ได้ [ 1 ]constexprconstconstexpr

คำหลักเพิ่มเติมในตระกูลคำหลัก " " ของ C++ constได้แก่consteval[ 3 ]ซึ่งใช้สำหรับรับประกันว่าฟังก์ชันจะทำงานในเวลาคอมไพล์และเวลาคอมไพล์เท่านั้น และ ซึ่งใช้สำหรับรับประกันระยะเวลาการจัดเก็บแบบคงที่/เธรด เพื่อ constinitให้แน่ใจว่ามีการเริ่มต้นในเวลาคอมไพล์ (แต่ไม่ใช่ความไม่เปลี่ยนแปลง) [ 4 ]

พื้นหลัง

คำนี้constexprเป็นคำผสมของconstant expression [ 5 ]ซึ่งถูกนำมาใช้ครั้งแรกในC++11ก่อนที่จะมีการนำ มาใช้constexprตัวเลือกสำหรับการระบุค่าคงที่และฟังก์ชันในเวลาคอมไพล์ใน C++ นั้นจำกัดอยู่เฉพาะมาโครพรีโปรเซสเซอร์ (เช่น#define PI 3.1415926535หรือมาโครเชิงกระบวนการเช่น#define SQUARE(x) ((x) * (x))) ซึ่งทำการแทนที่ข้อความและขาดความปลอดภัยของประเภทเช่นเดียวกับคุณสมบัติหลักของภาษา หรือการประกาศค่าคงที่แบบแจงนับ (เช่น) ซึ่งจำกัดเฉพาะประเภทจำนวนเต็มเท่านั้น แรงจูงใจที่สำคัญประการหนึ่งในการพัฒนาการแสดงออกในเวลาคอมไพล์คือแม้ว่าจะเทียบเท่ากับมาโครแต่ก็สร้างการแสดงออกที่ไม่ใช่ค่าคงที่[ 6 ]enum{WINDOW_SIZE=600};std::numeric_limits<T>::max()INT_MAX

ข้อเสนอเบื้องต้นสำหรับนิพจน์ค่าคงที่ทั่วไปและนิพจน์เวลาคอมไพล์ได้รับการเสนอให้รวมไว้ใน C++ โดย Gabriel Dos Reis ในปี 2003 [ 7 ]โดยเสนอให้ขยายนิพจน์ค่าคงที่ให้รวมถึงฟังก์ชันค่าคงที่ซึ่งเป็นฟังก์ชันที่สามารถประเมินค่าได้ในเวลาคอมไพล์ โดยมีเป้าหมายเฉพาะคือการปรับปรุงความปลอดภัยของประเภทและความสามารถในการพกพา[ 6 ]ข้อเสนอนี้ได้รับการแก้ไขเพิ่มเติมโดยการเขียนร่วมของBjarne Stroustrupและ Jens Maurer ในปี 2006 เพื่อแนะนำconstexprคำหลัก พร้อมกับการรวมลิเทอรัลที่ผู้ใช้กำหนด (วัตถุของประเภทที่ผู้ใช้กำหนดพร้อมconstexprตัวสร้างและตัวทำลาย) เข้าไว้ในคำจำกัดความของนิพจน์ค่าคงที่[ 6 ]และได้รับการนำไปใช้ในร่างสำหรับ C++11 ในเดือนกรกฎาคม 2007 [ 8 ] Herb Sutterประธานคณะกรรมการ C++ ในปี 2026 ได้อธิบายการนำไปใช้constexprว่าเป็นหนึ่งในการลงคะแนนเสียงที่ 'สำคัญที่สุด' ในประวัติศาสตร์ของ C++ [ 9 ]

C++20ยังได้แนะนำคีย์เวิร์ดสองคำของ " constตระกูล" ได้แก่constevalและ[ 10 ] [ 11 ]ด้วยการแนะนำการสะท้อน ในเวลาคอมไพล์ ใน C++26 จึงมีการเสนอตัวแปร แต่ไม่ได้ถูกเพิ่มเข้ามา[ 12 ]constinitconsteval

constexprต่อมาได้มีการนำเข้าสู่ C โดยเริ่มตั้งแต่C23 [ 2 ] [ 13 ]

ความหมาย

การใช้งานหลัก คือการอนุญาตให้ประเมินการคำนวณที่ซับซ้อนในระหว่างการคอมไพล์ หลีกเลี่ยงค่าใช้จ่าย เพิ่มเติมconstexprในระหว่างการทำงาน เช่น เฟรมสแต็กหรือหน่วยความจำเพิ่มเติม[ 5 ]โดยไม่ต้องพึ่งพาคำสั่งพรีโปรเซสเซอร์ รวมถึงป้องกันพฤติกรรมที่ไม่กำหนด ในบางกรณี [ 14 ]

ตัวแปร

ตัวแปรหรือแม่แบบตัวแปรอาจถูกประกาศได้หากเป็นคำจำกัดความ เป็นประเภทตัวอักษร มีการเริ่มต้นที่การประกาศ และสามารถเริ่มต้นด้วยค่าคงที่ได้[ 15 ] ตัวแปร ดังกล่าวจะถูกทำให้เป็น const โดยปริยาย การอ้างอิงอาจทำได้โดย มีเงื่อนไข ว่าต้องเริ่มต้นด้วยนิพจน์ค่าคงที่ และการแปลงโดยปริยายใดๆ ที่เรียกใช้ระหว่างการเริ่มต้นก็เป็นนิพจน์ค่าคงที่เช่นกัน[ 5 ]constexprconstexprconstexpr

import std ;โดยใช้std :: array ;// ประกาศค่าคงที่ในขั้นตอนการคอมไพล์constexpr double EARTH_GRAVITATIONAL_ACCELERATION = 9.8 ; constexpr double MOON_GRAVITATIONAL_ACCELERATION = EARTH_GRAVITATIONAL_ACCELERATION / 6.0 ; constexpr size_t MAX_LENGTH = 500 ;// สร้างอาร์เรย์ของจำนวนเต็มที่มีความยาว 500 โดยใช้ค่าคงที่ MAX_LENGTH ที่กำหนดไว้ในระหว่างการคอมไพล์array < int , MAX_LENGTH > numbers ;

C++26อนุญาตให้constexprมีการผูกโครงสร้าง[ 16 ]ซึ่งอาจผูกกับประเภทรวม (เช่นstructs ) อาร์เรย์และคู่/ทูเปิ[ 17 ]

struct Point { int x ; int y ; };constexpr int NUMS [ 3 ] = { 1 , 2 , 3 };// a = 1, b = 5 constexpr auto [ a , b ] = Point {. x = 1 , . y = 5 }; // id = 3, name = "John Doe", score = 95 constexpr auto [ id , name , score ] = std :: make_tuple ( 3 , "John Doe" , 95 ); // x = 1, y = 2, z = 3 constexpr auto [ x , y , z ] = NUMS ;

คำแนะนำและข้อมูลอ้างอิง

ในภาษา C ตัวชี้ (ยกเว้นnullptr), ชนิดข้อมูลที่แก้ไขได้แบบแปรผัน, ชนิดข้อมูลอะตอมิกและ ชนิดข้อมูล แบบระเหยได้อาจ ไม่ใช่constexpr

ในภาษา C++ constexprตัวชี้และการอ้างอิงอยู่ภายใต้ข้อจำกัดที่แตกต่างจากconstexprตัวแปรทั่วไปเล็กน้อย สำหรับconstexprตัวชี้ ที่อยู่ของตัวชี้จะต้องเป็นที่อยู่ของตัวแปรที่มี ระยะเวลา การจัดเก็บแบบคงที่และเป็นตัวชี้คงที่การคำนวณทางคณิตศาสตร์ของตัวชี้บนที่อยู่เหล่านี้ (หากไม่ใช่อาร์เรย์ ) และที่อยู่ของตัวแปรในสแต็กจะไม่ถือเป็นนิพจน์คงที่

import std ;int main () { int x = 3 ; static float val = 3.0f ;// ข้อผิดพลาด (ระยะเวลาการจัดเก็บอัตโนมัติ) // constexpr int* ptr = &x;// ตกลง (ระยะเวลาการจัดเก็บแบบคงที่) constexpr float * address = & val ; * address = 4.5f ;std :: println ( "{}" , val ); // พิมพ์ 4.5 }

ในขณะเดียวกันconstexprการอ้างอิงจะผูกกับตัวแปรที่มีระยะเวลาการจัดเก็บแบบคงที่หรือconstexprตัวแปร (โดยไม่คำนึงถึงระยะเวลาการจัดเก็บ) เท่านั้น [ 17 ]

import std ;int main () { static char ch = 'A' ; constexpr char & ref1 = ch ; ref1 = 'c' ; std :: println ( "{}" , ref1 ); // พิมพ์ 'c'constexpr int จำนวน= 100 ; constexpr int & ref2 = หมายเลข;std :: println ( "{}" , ref2 - 2 ); // พิมพ์ 98 }

ฟังก์ชัน

ฟังก์ชันconstexprคือฟังก์ชันที่ค่าส่งคืนสามารถคำนวณได้ในเวลาคอมไพล์ (เช่น เมื่ออาร์กิวเมนต์เป็นนิพจน์คงที่) และเมื่อเรียกใช้ในเวลารันไทม์ จะทำงานเหมือนฟังก์ชันทั่วไป[ 5 ]ฟังก์ชันconstexprที่ประเมินในเวลาคอมไพล์จะหยุดการคอมไพล์เมื่อเกิดพฤติกรรมที่ไม่กำหนด[ 14 ]constexprฟังก์ชันเป็นแบบอินไลน์ โดยปริยาย [ 1 ]

constexpr double div ( double a , double b ) noexcept { return a / b ; }constexpr double x = div ( 1 , 0 ); // ป้องกันการคอมไพล์ เนื่องจากเรียกใช้พฤติกรรมที่ไม่กำหนดไว้

constexprเนื่องจาก สามารถทราบ ประเภทค่าส่งคืนของ ฟังก์ชันได้ในระหว่างการคอมไพล์ จึงสามารถเรียกใช้ฟังก์ชันเหล่านั้นในระหว่างการคอมไพล์เพื่อใช้ในนิพจน์ที่เรียกใช้ในระหว่างการคอมไพล์ได้

constexpr int getFive () noexcept { return 5 ; }int numbers [ getFive () + 7 ]; // สร้างอาร์เรย์ของจำนวนเต็ม 12 ตัว

โครูทีนอาจไม่ใช่constexprในอดีตconstexprฟังก์ชันมีข้อจำกัดมากกว่ามาก รวมถึงการไม่อนุญาตให้มีreturnคำสั่ง หลายรายการ tryบล็อก และ บล็อก แอสเซมบลีแบบอินไลน์ซึ่งทั้งหมดนี้ได้รับการผ่อนปรนลงเรื่อยๆ ในแต่ละการแก้ไข[ 1 ] [ 18 ]

C++17 อนุญาตให้ใช้ประเภทปิด และฟังก์ชันแลมบ์ดาในเนื้อหาการประเมินค่าคงที่ [ 19 ]

เมธอดคลาสและตัวดำเนินการโอเวอร์โหลดอาจถูกประกาศด้วยconstexpr. ก่อนC++14เมธอดconstexprมีconstการเข้าถึงโดยปริยาย ซึ่งทำให้ไม่สามารถจัดการคลาสได้[ 5 ]ก่อน C++20 ฟังก์ชันเสมือนไม่สามารถเป็นconstexpr. [ 1 ] [ 20 ]

ตัวสร้างและตัวทำลาย

คอนconstexprสตรัคเตอร์คือคอนสตรัคเตอร์ที่อนุญาตให้คลาสได้รับการเริ่มต้นและประกาศในระหว่างการคอมไพconstexprล์ คอนสตรัคเตอร์อยู่ภายใต้ข้อกำหนดเดียวกันกับconstexprฟังก์ชัน[ 19 ]จนถึงC++26คลาสที่มีvirtualคลาสพื้นฐานไม่สามารถมีconstexprคอนสตรัคเตอร์ได้ การแนะนำconstexprการสืบทอดเสมือนมุ่งหวังที่จะอนุญาตให้มีconstexprการจัดรูปแบบสตรีมผ่านconstexprคอนสตรัคเตอร์std::ios_baseใน ที่สุด [ 21 ]คอนสตรัคเตอร์ที่สร้างขึ้นโดยปริยายรับประกันว่าจะเป็นconstexprถ้าคลาสเป็นประเภทลิเทอรัล[ 22 ] [ 23 ]

ในขณะเดียวกัน ตัวconstexprทำลาย (ที่นำมาใช้ในC++20 ) เป็นตัวทำลายที่อนุญาตให้ทำลายวัตถุในระหว่างการคอมไพล์ เช่นเดียวกับตัวสร้างconstexprตัวทำลายก็อยู่ภายใต้ข้อกำหนดเดียวกันกับconstexprฟังก์ชัน[ 19 ]แรงจูงใจหลักในการนำconstexprตัวทำลายมาใช้คือการอนุญาตให้ใช้คลาสที่ไม่ธรรมดาในระหว่างการคอมไพล์ เช่นstd::stringและstd::vectorซึ่งคลาสหลังนี้ถูกใช้อย่างกว้างขวางใน API ของการสะท้อน ในระหว่างการคอมไพ ล์std::metaของ[ 24 ]ซึ่งตอนนี้อนุญาตให้มีการจัดสรรและการทำลายที่ไม่ธรรมดาในบริบทการคอมไพล์[ 25 ]ตัวทำลายที่สร้างขึ้นโดยปริยายจะรับประกันว่าเป็นถ้าคลาสเป็นประเภทลิเทอรัล[ 26 ]เช่นเดียวกับตัวสร้างตัวทำลายในอดีตไม่อนุญาตให้ทำลายคลาสที่มีคลาสพื้นฐาน ใน C++26 คลาส ไลบรารีมาตรฐาน ต่างๆ ซึ่งในอดีตใช้ได้เฉพาะในขณะรันไทม์เท่านั้น ได้ถูกทำให้สามารถใช้ได้ในระหว่างการคอมไพล์ผ่านตัวทำลาย[ 27 ]constexprconstexprconstexprvirtualconstexpr

คลาสที่มีสมาชิกแบบคงที่ซึ่งเป็นอินสแตนซ์ของตัวมันเองอาจเป็นไปได้constexprแต่ฟิลด์ภายในคลาสจะต้องได้รับการประกาศก่อนconstในขณะที่constexprการประกาศจะต้องอยู่นอกคลาส การพยายามใช้การประกาศอินconstexprสแตนซ์ของคลาสเป็น สมาชิก แบบคงที่ของตัวมันเองจะล้มเหลว เนื่องจากไม่มีคำจำกัดความของวัตถุใดๆ ที่อาจเป็นประเภทที่ไม่สมบูรณ์ ซึ่งคลาสจะไม่สมบูรณ์จนกว่าจะปิด[ 28 ]

struct Color { uint8_t r ; uint8_t g ; uint8_t b ;constexpr Color ( uint8_t r , uint8_t g , uint8_t b ) noexcept : r { r }, g { g }, b { b } {}constexpr ~ Color () = default ;static const Color BLACK ; static const Color RED ; static const Color GREEN ; static const Color YELLOW ; static const Color BLUE ; static const Color MAGENTA ; static const Color CYAN ; static const Color WHITE ; };inline constexpr Color Color :: BLACK = Color ( 0 , 0 , 0 ); inline constexpr Color Color :: RED = Color ( 255 , 0 , 0 ); inline constexpr Color Color :: GREEN = Color ( 0 , 255 , 0 ); inline constexpr Color Color :: YELLOW = Color ( 255 , 255 , 0 ); inline constexpr Color Color :: BLUE = Color ( 0 , 0 , 255 ); inline constexpr Color Color :: MAGENTA = Color ( 255 , 0 , 255 ); inline constexpr Color Color :: CYAN = Color ( 0 , 255 , 255 ); inline constexpr Color Color :: WHITE = Color ( 255 , 255 , 255 );

คำสั่ง if ในขั้นตอนการคอมไพล์

C++ มีคำสั่ง if ใน เวลาคอมไพล์สองรูปแบบ ได้แก่if constexprและif consteval[ 29 ]

แบบแรกif constexprซึ่งแนะนำในC++17อนุญาตให้มีการแตกแขนงแบบมีเงื่อนไขในเวลาคอมไพล์ โดยกำหนดให้เงื่อนไขต้องเป็นนิพจน์คงที่ที่สามารถแปลงเป็นได้bool[ 29 ] จะif constexprทิ้งแขนงที่ไม่เกิดขึ้น ทำให้ไม่สามารถคอมไพล์ได้ ซึ่งช่วยให้สามารถคอมไพล์แบบมีเงื่อนไขได้โดยไม่ต้องใช้พรีโปรเซสเซอร์ อย่างไรก็ตาม แขนงที่ถูกทิ้ง แม้ว่าจะไม่ได้คอมไพล์ คอมไพเลอร์ก็ยังต้องการให้ถูกต้องตามหลักไวยากรณ์หรือได้รับการยอมรับ[ 30 ]returnคำสั่งในคำสั่งที่ถูกทิ้งจะไม่เข้าร่วมในการอนุมานประเภท การส่งคืน ของ ฟังก์ชัน

import std ;using std :: conditional_t ; using std :: is_pointer_v ; using std :: remove_pointer_t ;template < typename T > constexpr auto getValue ( T t ) noexcept -> conditional_t ​​< is_pointer_v < T > , remove_pointer_t < T > , T > { if constexpr ( is_pointer_v < T > ) { return * t ; } else { return t ; } }int main () { int * numbers = new int [ 5 ]{ 1 , 2 , 3 , 4 , 5 }; int firstNumber = getValue ( numbers ); int five = getValue ( 5 );ลบตัวเลข; }

ส่วนหลังif constevalซึ่งแนะนำในC++23ทำหน้าที่เป็นif constexprเงื่อนไขว่าเงื่อนไขนั้นifจะถูกประเมินในเวลาคอมไพล์หรือไม่ แทนที่จะเป็นเวลารันไทม์[ 31 ]

template < typename T > constexpr T * arrayOfLength ( size_t n ) { if consteval { // อาร์เรย์ต้องไม่หลุดออกจากขอบเขตของนิพจน์ในเวลาคอมไพล์return nullptr ; } else { // ในเวลารันไทม์ อนุญาตให้ส่งคืนพอยเตอร์ไปยังอาร์เรย์ที่จัดสรรในฮีปreturn new T [ n ]; } }

if constevalแนะนำไวยากรณ์เพิ่มเติม: เทียบเท่ากับ. [ 29 ]if!consteval{/* stmt1 */}else{/* stmt2 */}ifconsteval{/* stmt2 */}else{/* stmt1 */}

วิวัฒนาการ

ตัวconstexprระบุได้มีการพัฒนาไปตามการแก้ไขมาตรฐาน C++ แต่ละครั้ง โดยมีการยกเลิกข้อจำกัดconstexprหรือแนะนำบริบทใหม่สำหรับการใช้งานคำหลักดังกล่าว ดังเช่นconstexprในC++11ที่มีข้อจำกัดมากกว่าใน C++ รุ่นปัจจุบันมาก

ซี++11

ในร่างC++11ปี 2008 constexprอนุญาตให้ฟังก์ชันเรียกตัวเองแบบเรียกซ้ำได้ [ 32 ] ต่อมาในปี 2010 ฟังก์ชัน constexpr อนุญาตให้ส่งพารามิเตอร์เป็น const-reference ได้[ 33 ]และในปี 2011 อนุญาตให้มี static_assertการตรวจสอบและusingคำสั่งภายในบริบทของconstexprฟังก์ชันได้[ 34 ]ในมาตรฐาน C++11 ฉบับสุดท้ายconstexprอนุญาตให้ฟังก์ชันมีคำสั่ง return เพียงคำสั่ง เดียวเท่านั้น [ 1 ]

ซี++14

C++14ยกเลิกข้อจำกัดที่ว่าconstexprเมธอดทั้งหมดเป็นแบบโดยปริยายconstทำให้constexprเมธอดสามารถเปลี่ยนค่าของตัวแปรสมาชิกได้[ 5 ]

C++14 อนุญาตให้ใช้คำสั่ง return หลายรายการบล็อกควบคุมการไหลเช่นif/ elseและลูปswitchและการ ประกาศ ตัวแปรภายในฟังก์ชัน[ 35 ] C++14 ยังอนุญาตให้ฟังก์ชัน constexpr มีประเภทการคืนค่า ตัวอย่างต่อไปนี้แสดงตัวตรวจสอบจำนวนเฉพาะซึ่งทำงานในเวลาคอมไพล์ constexprvoid

constexpr bool isPrime ( uint64_t number ) noexcept { if ( number < 2 ) { return false ; } else if ( number == 2 || number == 3 ) { return true ; } else if ( number % 2 == 0 || number % 3 == 0 ) return false ; } for ( uint64_t i = 5 ; i * i <= number ; i += 6 ) { if ( number % i == 0 || number % ( i + 2 ) == 0 ) { return false ; } } return true ; }static_assert ( isPrime ( 264223787557 ));

ซี++17

C++17ระบุว่าconstexprตัวระบุในการประกาศฟังก์ชันหรือตัวแปรสมาชิกแบบคงที่ทำให้เป็นอินไลน์โดย ปริยาย [ 1 ] C++17 ได้แนะนำซึ่งมีอิทธิพลต่อ การเขียนโปรแกรมเม ตาเทมเพลต[ 29 ]if constexpr

ตั้งแต่ C++17 เป็นต้นมาสามารถใช้ ประเภทปิดและ ฟังก์ชันแลมบ์ดา ในนิพจน์คงที่ได้ [ 19 ]แลมบ์ดาทั้งหมดเป็นแบบโดยconstexprปริยาย[ 19 ]

constexpr int FACTOR = 10 ;constexpr auto scaleBy = [ FACTOR ]( int x ) -> int { return x * FACTOR ; };static_assert ( scaleBy ( 4 ) == 40 );

ซี++20

C++20ผ่อนคลายข้อจำกัดสำหรับconstexprการประเมินในบริบทต่างๆ[ 19 ] [ 20 ] [ 25 ]รวมถึงการเรียกฟังก์ชันเสมือน การจัดสรรฮีปชั่วคราว ตัวconstexprทำลาย[ 1 ] [ 25 ]และอื่นๆการจัดสรรฮีปในconstexprบริบทจะต้องทราบว่าถูกยกเลิกการจัดสรรภายในconstexprบริบท[ 25 ]

C++20 ยกเลิกข้อจำกัดเกี่ยวกับเมธอดconstexprเสมือน[ 1 ] [ 20 ]

คลาสBase { public : virtual constexpr size_t f () const { return sizeof ( int ); }constexpr virtual ~ Base () = default ; };คลาสMyIntArray : public Base { private : int * a ; const size_t length ; public : constexpr size_t f () const override { return length ; }constexpr MyIntArray ( size_t n ) : a { new int [ n ]}, length { n } {}constexpr ~ MyIntArray () override { delete [] a ; }constexpr int & operator []( size_t i ) { return a [ i ]; }constexpr const int & operator []( size_t i ) const { return a [ i ]; }MyIntArray ( const MyIntArray & ) = delete ; MyIntArray & operator = ( const MyIntArray & ) = delete ; };

ซี++23

C++23อนุญาตให้ฟังก์ชันมีgotoคำสั่งtryบล็อกตัวแปรคงที่และแอสเซมบลีแบบอินไลน์[ 1 ] C++23 ยังแนะนำเพิ่มเติมอีกif constevalด้วย[ 29 ]

ซี++26

C++26อนุญาตให้ใช้การสืบทอดเสมือนในคอนสตรัคเตอร์และดีสตรัคเตอร์ที่ประกาศด้วยconstexpr. [ 21 ]constexprเพิ่มการสนับสนุน การผูกโครงสร้าง [ 17 ]การconstexprแปลงจากvoid*[ 36 ]การconstexprสร้างใหม่ แบบวาง [ 37 ]รวมถึงconstexprการโยนข้อยกเว้น[ 38 ]constexprมีการแนะนำการสนับสนุนเพิ่มเติมสำหรับ ประเภทไลบรารีมาตรฐาน [ 27 ]

Hana Dusíková ได้เผยแพร่ ข้อเสนอสำหรับconstexprcoroutinesในปี 2025 เพื่อนำไปใช้ใน C++26 แต่ถูกเลื่อนไปเป็น C++29 [ 39 ]

consteval

constevalเป็นตัวระบุฟังก์ชันที่ระบุว่าฟังก์ชันนั้นเป็น "ฟังก์ชันทันที" [ 10 ]กล่าวคือ การเรียกใช้ฟังก์ชันทุกครั้งจะต้องสร้างนิพจน์ค่าคงที่ในเวลาคอมไพล์ กล่าวอีกนัยหนึ่ง ฟังก์ชันนั้นสามารถดำเนินการได้เฉพาะในเวลาคอมไพล์เท่านั้น [ 3 ]หากคอมไพเลอร์ไม่สามารถประเมินการเรียกใช้ในเวลาคอมไพล์ได้ โปรแกรมจะไม่สามารถคอมไพล์ได้ [ 40 ]constevalนอกจากนี้ยังใช้สำหรับif constevalบล็อกด้วย [ 29 ]

import std ;โดยใช้std :: array ;consteval int square ( int x ) { return x * x ; }template < size_t N > consteval array < int , N > squaresUpTo () { array < int , N > squares ; for ( size_t i = 0 ; i < N ; ++ i ) { squares [ i ] = square ( i ); } return squares ; }int main () { constexpr int a = square ( 5 ); // OK: ประเมินผลในระหว่างการคอมไพล์// ตกลง: ประเมินผลในระหว่างการคอมไพล์เนื่องจาก square() เป็นค่าคงที่int b = square ( 5 ) ; constexpr array < int , 5 > table = squaresUpTo <5> ( ); int x = 3 ; // ตกลง: x ไม่ใช่นิพจน์ค่าคงที่// int y = square(x); }

constinit

constinitเป็นตัวระบุตัวแปรที่รับประกันการเริ่มต้นแบบ คงที่ โดยมีระยะเวลาคงที่ /ทั่วโลกหรือการจัดเก็บแบบเธรด (จะทำให้เกิดข้อผิดพลาดในการคอมไพล์หากใช้กับตัวแปรโลคอลหรือหากไม่สามารถเริ่มต้นได้ในระหว่างการคอมไพล์ [ 4 ]ไม่ได้หมายความถึงความไม่เปลี่ยนแปลง ดังนั้นจึงสามารถมองได้ว่าเป็นตัวแปรที่เปลี่ยนแปลงได้ในระหว่างการคอมไพล์ [ 40 ]อาจไม่สามารถใช้ร่วมกับ ได้แต่เมื่อตัวแปรที่ประกาศเป็นการอ้างอิงจะเทียบเท่ากับไม่บังคับให้มีการทำลายหรือคุณสมบัติคงที่อนุญาตให้วัตถุที่มีตัวสร้างแต่ไม่มีตัวทำลาย thread_localconstinitconstinitconstinitconstexprconstexprconstinitconstconstexprconstexpr

const char * g () { return "การเริ่มต้นแบบไดนามิก" ; }constexpr const char * f ( bool b ) { return b ? "ตัวกำหนดค่าคงที่" : g (); }// ตกลง: เริ่มต้นใช้งานในระหว่างการคอมไพล์constinit const char * s1 = f ( true );// ไม่ถูกต้อง: g() ไม่ใช่นิพจน์คงที่// constinit const char* s2 = f(false);

constinitใช้เพื่อป้องกันสิ่งที่เรียกว่า "ความล้มเหลวของลำดับการเริ่มต้นแบบคงที่" ซึ่งวัตถุทั่วโลก (หรือคงที่) ในหน่วยการแปลที่แตกต่างกันจะถูกเริ่มต้นในลำดับที่ไม่ระบุ[ 11 ]

ในภาษาอื่นๆ

สิ่งที่เทียบเท่าconstexprในภาษาอื่น ๆ ได้แก่constในC# [ 41 ]และRust [ 42 ]ซึ่งประกาศสัญลักษณ์ให้เป็นแบบคอมไพล์ไทม์ นอกจากนี้ Rust ยังมีconst fnซึ่งเทียบเท่ากับconstexprฟังก์ชันใน C++ [ 43 ]constในGoอนุญาตให้ใช้ค่าคงที่แบบคอมไพล์ไทม์ได้ แต่ไม่อนุญาตให้ใช้ฟังก์ชัน[ 44 ] Zigมีcomptimeคีย์เวิร์ด เพื่อบังคับให้โค้ดทำงานเมื่อคอมไพล์ไทม์[ 45 ]

ไลบรารีJavaมีnet.onedaybeard.constexprคำอธิบายประกอบ@ConstExprที่จำลองconstexprจาก C++ ใน Java [ 46 ]ในขณะเดียวกัน ตัวแปรที่ประกาศด้วยstatic finalและของประเภทพื้นฐานหรือjava.lang.Stringถือว่าเป็นนิพจน์คงที่[ 47 ]

ดูเพิ่มเติม

ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Constexpr&oldid=1356337537 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ คอนเท็กซ์พอาร์

constexpr เป็นคำหลักระบุใน ภาษาการเขียนโปรแกรม C และ C++ ซึ่งโดยคร่าวๆ แล้วระบุว่าบางสิ่งอาจถูกประเมินใน เวลาคอมไพล์ [ 1 ] แตก ต่างจาก const...

พื้นหลัง

คำนี้ constexpr เป็นคำผสมของ constant expression [ 5 ] ซึ่งถูกนำมาใช้ครั้งแรกใน C++11 ก่อนที่จะมีการนำ มาใช้ constexpr ตัวเลือกสำหรับการระบุค่าคงที่และฟังก์ชันในเวลาคอมไพล์ใน C++ นั้นจำกัดอยู่เฉพาะ มาโครพรีโปรเซสเซอร์ (เช่น #define PI 3.

ความหมาย

การใช้งานหลัก คือการอนุญาตให้ประเมินการคำนวณที่ซับซ้อนในระหว่างการคอมไพล์ หลีกเลี่ยงค่าใช้จ่าย เพิ่มเติม constexpr ในระหว่างการทำงาน เช่น เฟรมสแต็กหรือหน่วยความจำเพิ่มเติม [ 5 ] โดยไม่ต้องพึ่งพาคำสั่งพรีโปรเซสเซอร์ รวมถึงป้องกัน พฤติกรรมที่ไม่กำหนด ในบางกรณี...

ตัวแปร

ตัวแปรหรือ แม่แบบตัวแปร อาจถูกประกาศได้หากเป็นคำจำกัดความ เป็นประเภทตัวอักษร มีการเริ่มต้นที่การประกาศ และสามารถเริ่มต้นด้วยค่าคงที่ได้ [ 15 ] ตัวแปร ดังกล่าวจะถูกทำให้ เป็น const โดยปริยาย การอ้างอิงอาจทำได้ โดย มีเงื่อนไข ว่าต้องเริ่มต้นด้วยนิพจน์ค่าคงที่...