คำถามติดแท็ก constexpr

constexpr เป็นโมดิฟายเออร์ที่นำมาใช้ใน C ++ 11 ซึ่งแจ้งคอมไพเลอร์ว่าทราบค่าของฟังก์ชันหรือตัวแปรหรือสามารถคำนวณได้ในเวลาคอมไพล์ ด้วยเหตุนี้จึงสามารถใช้เป็นค่าคงที่ในสถานที่ที่เป็นอย่างอื่นไม่ได้


14
เมื่อใดที่คุณควรใช้ความสามารถของ constexpr ใน C ++ 11
ดูเหมือนว่าสำหรับฉันแล้วการมี "ฟังก์ชั่นที่ส่งกลับค่า 5" จะทำลายหรือทำให้ความหมายของ "การเรียกใช้ฟังก์ชัน" ลดลง ต้องมีเหตุผลหรือต้องการความสามารถนี้มิเช่นนั้นจะไม่อยู่ใน C ++ 11 ทำไมถึงอยู่ที่นั่น? // preprocessor. #define MEANING_OF_LIFE 42 // constants: const int MeaningOfLife = 42; // constexpr-function: constexpr int MeaningOfLife () { return 42; } สำหรับฉันดูเหมือนว่าถ้าฉันเขียนฟังก์ชันที่ส่งคืนค่าตามตัวอักษรและฉันได้รับการตรวจสอบโค้ดใครบางคนจะบอกฉันฉันก็ควรจะประกาศค่าคงที่แทนการเขียนส่งคืน 5
337 c++  c++11  constexpr 

4
const vs constexpr กับตัวแปร
มีความแตกต่างระหว่างคำจำกัดความต่อไปนี้หรือไม่? const double PI = 3.141592653589793; constexpr double PI = 3.141592653589793; หากไม่ต้องการรูปแบบใดใน C ++ 11

2
ตัวแปร constexpr แบบคงที่ภายในฟังก์ชั่นเหมาะสมหรือไม่?
ถ้าฉันมีตัวแปรภายในฟังก์ชั่น (พูดเป็นอาร์เรย์ขนาดใหญ่) มันทำให้รู้สึกถึงการประกาศมันทั้งสองstaticและconstexpr? constexprรับประกันได้ว่าอาร์เรย์จะถูกสร้างขึ้นในเวลารวบรวมดังนั้นจะstaticไร้ประโยชน์หรือไม่? void f() { static constexpr int x [] = { // a few thousand elements }; // do something with the array } เป็นstaticสิ่งที่ทำจริงมีในแง่ของการสร้างรหัสหรือความหมาย?
193 c++  static  c++11  constexpr 

6
การอ้างอิงที่ไม่ได้กำหนดถึง constexpr แบบคงที่ []
ฉันต้องการstatic const charอาร์เรย์ในชั้นเรียนของฉัน GCC บ่นและบอกว่าฉันควรใช้constexprถึงแม้ว่าตอนนี้มันจะบอกฉันว่ามันเป็นข้อมูลอ้างอิงที่ไม่ได้กำหนด ถ้าฉันทำให้อาร์เรย์ไม่ใช่สมาชิกแล้วมันจะรวบรวม เกิดอะไรขึ้น? // .hpp struct foo { void bar(); static constexpr char baz[] = "quz"; }; // .cpp void foo::bar() { std::string str(baz); // undefined reference to baz }

4
เป็นไปได้ไหมที่จะใช้ std :: string ใน constexpr
โดยใช้ C ++ 11, อูบุนตู 14.04, toolchain รหัสนี้ล้มเหลว: constexpr std::string constString = "constString"; ข้อผิดพลาด: ประเภท 'สตริง const {aka const std :: basic_string}' ของตัวแปร constexpr 'constString' ไม่ใช่ตัวอักษร ... เพราะ ... 'std :: basic_string' มี destructor ที่ไม่สำคัญ เป็นไปได้ที่จะใช้std::stringในconstexpr? (เห็นได้ชัดว่าไม่ใช่ ... ) ถ้าเป็นเช่นนั้นได้อย่างไร มีวิธีอื่นในการใช้สตริงอักขระในconstexpr?

2
constexpr หมายถึงอินไลน์หรือไม่?
พิจารณาฟังก์ชันอินไลน์ต่อไปนี้: // Inline specifier version #include<iostream> #include<cstdlib> inline int f(const int x); inline int f(const int x) { return 2*x; } int main(int argc, char* argv[]) { return f(std::atoi(argv[1])); } และเวอร์ชันที่เทียบเท่า constexpr: // Constexpr specifier version #include<iostream> #include<cstdlib> constexpr int f(const int x); constexpr int f(const int x) { return …

2
“ พิษต่อฟังก์ชัน” ใน C ++ หมายความว่าอย่างไร?
ในตอนท้ายของการพูดคุย"แนะนำconstexpr"ของ Scott Schurr ที่ CppConเขาถามว่า "มีวิธีทำให้ฟังก์ชันเป็นพิษหรือไม่"? จากนั้นเขาอธิบายว่าสิ่งนี้สามารถทำได้ (แม้ว่าจะเป็นวิธีที่ไม่ได้มาตรฐาน) โดย: วางthrowในconstexprฟังก์ชั่น การประกาศยังไม่ได้รับการแก้ไข extern const char* การอ้างถึงสิ่งที่ยังไม่ได้แก้ไขexternในไฟล์throw ฉันรู้สึกว่าฉันไม่ได้อยู่ในส่วนลึกของฉันที่นี่ แต่ฉันอยากรู้: "พิษต่อหน้าที่" หมายความว่าอย่างไร? ความสำคัญ / ประโยชน์ของเทคนิคที่เขาสรุปคืออะไร?
96 c++  constexpr 

6
ความยาวการคำนวณของสตริง C ในเวลาคอมไพล์ นี่คือ constexpr จริงๆหรือ?
ฉันกำลังพยายามคำนวณความยาวของสตริงลิเทอรัลในเวลาคอมไพล์ ในการทำเช่นนั้นฉันใช้รหัสต่อไปนี้: #include <cstdio> int constexpr length(const char* str) { return *str ? 1 + length(str + 1) : 0; } int main() { printf("%d %d", length("abcd"), length("abcdefgh")); } ทุกอย่างทำงานตามที่คาดไว้โปรแกรมจะพิมพ์ 4 และ 8 รหัสแอสเซมบลีที่สร้างขึ้นโดยเสียงดังแสดงว่าผลลัพธ์ถูกคำนวณในเวลาคอมไพล์: 0x100000f5e: leaq 0x35(%rip), %rdi ; "%d %d" 0x100000f65: movl $0x4, %esi 0x100000f6a: movl $0x8, %edx 0x100000f6f: …

3
Constexpr เทียบกับมาโคร
ฉันควรใช้มาโครที่ไหนและฉันควรใช้constexprที่ไหน โดยพื้นฐานแล้วพวกเขาไม่เหมือนกันหรือ? #define MAX_HEIGHT 720 เทียบกับ constexpr unsigned int max_height = 720;
92 c++  c++11  macros  constexpr 

3
ฉันจะรับความลึกของ std หลายมิติ :: เวกเตอร์ในเวลารวบรวมได้อย่างไร
ฉันมีฟังก์ชั่นที่ใช้หลายมิติstd::vectorและต้องการความลึก (หรือจำนวนมิติ) ที่จะส่งผ่านเป็นพารามิเตอร์เทมเพลต แทนที่จะเขียนโค้ดนี้ฉันอยากจะเขียนconstexprฟังก์ชั่นที่จะรับstd::vectorและคืนความลึกเป็นunsigned integerค่า ตัวอย่างเช่น: std::vector<std::vector<std::vector<int>>> v = { { { 0, 1}, { 2, 3 } }, { { 4, 5}, { 6, 7 } }, }; // Returns 3 size_t depth = GetDepth(v); สิ่งนี้จะต้องทำในเวลารวบรวมแต่เนื่องจากความลึกนี้จะถูกส่งผ่านไปยังฟังก์ชันเทมเพลตเป็นพารามิเตอร์เทมเพลต: // Same as calling foo<3>(v); foo<GetDepth(v)>(v); มีวิธีการทำเช่นนี้?

1
ตัวนับเวลารวบรวม C ++ ได้รับการตรวจสอบอีกครั้ง
TL; DR ก่อนที่คุณจะพยายามอ่านโพสต์นี้ให้รู้ว่า: พบวิธีแก้ไขปัญหาที่นำเสนอด้วยตัวเองแต่ฉันก็ยังอยากรู้ว่าการวิเคราะห์นั้นถูกต้องหรือไม่ ฉันได้จัดทำแพคเกจลงในfameta::counterชั้นเรียนที่สามารถแก้ไขนิสัยใจคอที่เหลืออยู่สองสามข้อ คุณสามารถค้นหาได้ใน GitHub ; คุณสามารถเห็นมันในการทำงานใน godbolt มันเริ่มต้นอย่างไร ตั้งแต่ Filip Roséenค้นพบ / คิดค้นในปี 2015 เวทมนตร์ดำที่รวบรวมเวลาอยู่ใน C ++ฉันได้รับการหมกมุ่นกับอุปกรณ์อย่างอ่อนโยนดังนั้นเมื่อ CWG ตัดสินใจว่าการทำงานต้องไปฉันผิดหวัง แต่ก็ยังหวังว่าใจของพวกเขา อาจมีการเปลี่ยนแปลงโดยแสดงกรณีการใช้งานที่น่าสนใจ จากนั้นสองสามปีที่ผ่านมาฉันตัดสินใจที่จะดูสิ่งนั้นอีกครั้งเพื่อให้uberswitch esสามารถซ้อนกันได้ - กรณีใช้ที่น่าสนใจในความคิดของฉัน - เพียงเพื่อค้นพบว่ามันจะไม่ทำงานอีกต่อไปกับเวอร์ชันใหม่ของ คอมไพเลอร์ที่มีอยู่แม้ว่าปัญหา 2118คือ (และยังคงเป็น ) ในสถานะเปิด: โค้ดจะคอมไพล์ แต่ตัวนับจะไม่เพิ่มขึ้น มีการรายงานปัญหาบนเว็บไซต์ของRoséenและเมื่อเร็ว ๆ นี้บน stackoverflow: C ++ รองรับเคาน์เตอร์เวลาคอมไพล์หรือไม่? ไม่กี่วันที่ผ่านมาฉันตัดสินใจลองแก้ไขปัญหาอีกครั้ง ฉันต้องการที่จะเข้าใจสิ่งที่มีการเปลี่ยนแปลงในคอมไพเลอร์ที่ทำให้ C ++ ที่ดูเหมือนจะยังคงใช้งานได้ไม่ทำงานอีกต่อไป ด้วยเหตุนี้ฉันจึงค้นหาผู้คนให้พูดคุยเกี่ยวกับเรื่องนี้อย่างกว้างขวางและห่างไกล …

1
gotchas ใด ๆ ที่แทนที่ global const char [] ด้วย constexpr string_view?
ทีมงานของเรากำลังทำงานกับรหัสฐาน C ++ อายุมากกว่า 10 ปีและเพิ่งเปลี่ยนเป็นคอมไพเลอร์ C ++ 17 ดังนั้นเรากำลังมองหาวิธีปรับปรุงรหัสของเราให้ทันสมัย ในการพูดคุยประชุมบน YouTube ผมได้ยินข้อเสนอแนะเพื่อแทนที่สตริงระดับโลกที่มีconst char*constexpr string_view เนื่องจากเรามีconst char*ค่าคงที่สตริงทั่วโลกจำนวนมากในรหัสของเราฉันต้องการถามว่ามี gotchas หรือปัญหาที่อาจเกิดขึ้นที่เราต้องระวังหรือไม่?

1
std :: pair <auto, auto> return type
ผมเล่นรอบกับในauto std::pairในรหัสด้านล่างฟังก์ชั่นfควรจะส่งกลับstd::pairประเภทซึ่งขึ้นอยู่กับพารามิเตอร์แม่แบบ ตัวอย่างการทำงาน: ตัวอย่าง 1 template &lt;unsigned S&gt; auto f() { if constexpr (S == 1) return std::pair{1, 2}; // pair of ints else if constexpr (S == 2) return std::pair{1.0, 2.0}; // pair of doubles else return std::pair{0.0f, 0.0f}; // pair of floats } ใช้งานได้กับ gcc 9.2, gcc 10.0, …

2
ทำไม std :: swap ที่ทำเครื่องหมายว่า constexpr ก่อน C ++ 20 ไม่
ใน C ++ 20 std::swapกลายเป็นconstexprฟังก์ชัน ฉันรู้ว่าห้องสมุดมาตรฐานล้าหลังภาษาในการทำเครื่องหมายสิ่งต่าง ๆconstexprแต่ในปี 2560 &lt;algorithm&gt;เป็นกลุ่มคนที่ค่อนข้างมากเหมือนกับสิ่งอื่น ๆ แต่ - std::swapไม่ใช่ ฉันจำได้ว่ามีข้อบกพร่องบางอย่างเกี่ยวกับภาษาแปลก ๆ ซึ่งป้องกันการทำเครื่องหมายนั้น แต่ฉันลืมรายละเอียด บางคนสามารถอธิบายสิ่งนี้อย่างกระชับและชัดเจน? แรงจูงใจ: จำเป็นต้องเข้าใจว่าเหตุใดจึงเป็นความคิดที่ไม่ดีที่จะทำเครื่องหมายstd::swap()ฟังก์ชันเหมือนconstexprในรหัส C ++ 11 / C ++ 14

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.