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

C ++ เป็นภาษาโปรแกรมทั่วไป เดิมได้รับการออกแบบให้เป็นส่วนขยายของ C และมีไวยากรณ์ที่คล้ายกัน แต่ตอนนี้มันเป็นภาษาที่แตกต่างอย่างสิ้นเชิง ใช้แท็กนี้สำหรับคำถามเกี่ยวกับรหัส (จะ) คอมไพล์ด้วยคอมไพเลอร์ C ++ ใช้แท็กเฉพาะรุ่นสำหรับคำถามที่เกี่ยวข้องกับการแก้ไขมาตรฐานเฉพาะ [C ++ 11], [C ++ 14], [C ++ 17] หรือ [C ++ 20] เป็นต้น

3
จะทราบได้อย่างไรว่าคอมไพเลอร์ตัวใดที่สร้างขึ้น?
ฉันรู้เกี่ยวกับฟังก์ชันที่คอมไพเลอร์สร้างขึ้น, กฎของสามและกฎห้า ในสถานการณ์โลกแห่งความจริงมันอาจไม่สำคัญที่จะเข้าใจว่าฟังก์ชั่นที่สร้างขึ้นโดยคอมไพเลอร์ (ผู้สร้างผู้ประกอบการที่ได้รับมอบหมายผู้ทำลายล้าง) ถูกสร้างขึ้นจริงโดยคอมไพเลอร์ มีวิธีใดบ้างในการแสดงรายการฟังก์ชันที่คอมไพเลอร์สร้างขึ้นสำหรับคลาสที่ระบุ? ฉันสนใจ Visual Studio 2019 และ Xcode เป็นหลัก แต่โซลูชันทั่วไปน่ายินดียิ่งกว่าเดิม
11 c++  c++11 

1
Unqualified sort () - ทำไมมันรวบรวมเมื่อใช้กับ std :: vector และไม่ได้อยู่ในอาร์เรย์ std :: และคอมไพเลอร์ใดที่ถูกต้อง?
เมื่อโทรstd::sort()บนstd::array: #include <vector> #include <array> #include <algorithm> int main() { std::vector<int> foo{4, 1, 2, 3}; sort(begin(foo), end(foo)); std::array<int, 4> foo2{4, 1, 2, 3}; sort(begin(foo2), end(foo2)); } ทั้ง gcc และ clang ส่งคืนข้อผิดพลาดในการเรียงลำดับบนstd::array- clang กล่าว ข้อผิดพลาด: การใช้ตัวระบุที่ไม่ได้ประกาศ 'sort'; หมายถึง 'std :: sort' หรือเปล่า การเปลี่ยนเป็นการstd::sort(begin(foo2), end(foo2))แก้ไขปัญหา MSVC รวบรวมรหัสข้างต้นตามที่เขียนไว้ ทำไมความแตกต่างในการรักษาระหว่างstd::vectorและstd::array; และคอมไพเลอร์ตัวใดที่ถูกต้อง?
11 c++  c++17 

2
จะหาการคัดลอกปลอมแบบ C ++ ได้อย่างไร?
เมื่อเร็ว ๆ นี้ฉันมีดังต่อไปนี้ struct data { std::vector<int> V; }; data get_vector(int n) { std::vector<int> V(n,0); return {V}; } ปัญหาของรหัสนี้คือเมื่อโครงสร้างถูกสร้างสำเนาเกิดขึ้นและวิธีแก้ไขคือแทนที่จะเขียนreturn {std :: move (V)} มีตัววิเคราะห์ linter หรือ code ที่ตรวจจับการดำเนินการคัดลอกปลอมหรือไม่ cppcheck, cpplint และ clang-tidy ไม่สามารถทำได้ แก้ไข: มีหลายประเด็นที่ทำให้คำถามของฉันชัดเจนขึ้น: ฉันรู้ว่าดำเนินการคัดลอกเกิดขึ้นเพราะผมเคยสำรวจคอมไพเลอร์และมันแสดงให้เห็นว่าการเรียกไปยังmemcpy ฉันสามารถระบุได้ว่าการคัดลอกเกิดขึ้นโดยดูจากมาตรฐานใช่ แต่ความคิดที่ผิดพลาดครั้งแรกของฉันคือคอมไพเลอร์จะทำสำเนานี้ให้เหมาะสมที่สุด ฉันผิดไป. มันเป็น (น่าจะ) ไม่เป็นปัญหาคอมไพเลอร์เนื่องจากทั้งสองเสียงดังกราวและ GCC รหัสผลิตผลที่ผลิตmemcpy memcpy อาจจะถูก แต่ฉันไม่สามารถจินตนาการสถานการณ์ที่คัดลอกหน่วยความจำและการลบเดิมมีราคาถูกกว่าการส่งผ่านตัวชี้โดยมาตรฐาน :: ย้าย การเพิ่มstd …

2
T ต้องเป็นประเภทที่สมบูรณ์ที่จะใช้ใน `std :: declval <T>` หรือไม่?
ลองพิจารณาตัวอย่างนี้ (มาจากที่นี่ ): #include &lt;type_traits&gt; #include &lt;iostream&gt; template &lt;typename U&gt; struct A { }; struct B { template &lt;typename F = int&gt; A&lt;F&gt; f() { return A&lt;F&gt;{}; } using default_return_type = decltype(std::declval&lt;B&gt;().f()); }; int main() { B::default_return_type x{}; std::cout &lt;&lt; std::is_same&lt; B::default_return_type, A&lt;int&gt;&gt;::value; } มันรวบรวมโดยไม่มีข้อผิดพลาดใน gcc9.2แต่ gcc7.2 และเสียงดังกราว 10.0.0 บ่นเกี่ยวกับการBไม่สมบูรณ์ …

5
destructor ของอ็อบเจ็กต์โลคัลภายในลูปรับประกันว่าจะถูกเรียกก่อนการวนซ้ำครั้งถัดไปหรือไม่?
เมื่อฉันมีลูปและภายในลูปนี้สร้างตัวแปรสแต็กใหม่ (ไม่จัดสรรในฮีปและตัวแปรที่เก็บไว้ที่ประกาศไว้ในเนื้อความลูป) เป็นตัวทำลายของวัตถุนี้รับประกันว่าจะถูกเรียกก่อนเริ่มการทำซ้ำครั้งถัดไปหรืออาจ วนรอบการคลี่คลายโดยคอมไพเลอร์เปลี่ยนอะไรบางอย่างเกี่ยวกับที่?
11 c++  destructor 

1
ตัวแปรอินไลน์สามารถเปลี่ยนแปลงได้หลังจากการเริ่มต้นใน C ++ 17 หรือไม่
สถานการณ์ของฉันเป็นดังต่อไปนี้ (มันทำงานในเสียงดังกราว แต่ไม่ได้อยู่ใน gcc) liba.hpp: inline int MY_GLOBAL = 0; libother.cpp: (dll) #include "myliba.hpp" void myFunc() { // MYGLOBAL = 28; } someexe.cpp: RunAppThatUsesBothLibAandLibOther(); ปัญหาคือตัวแปรอินไลน์แสดง 0 ในสถานที่ที่ฉันคาดไว้ 28 เพราะมันถูกแก้ไขอย่างมากในเวลาทำงาน MSVC ไม่เห็นด้วยกับสิ่งนี้ แต่เสียงดังทำตามที่ฉันคาดไว้ คำถามคือ: สามารถแก้ไขตัวแปรอินไลน์ในเวลาทำงานในสถานการณ์ของฉันได้หรือไม่ (ฉันแก้ไขปัญหาโดยการลบตัวแปรออกไป)
11 c++  visual-c++  dll  clang  c++17 

1
std :: ฟังก์ชั่น const ความถูกต้อง
สมมติว่าฉันมีประเภท callable ดังนี้ struct mutable_callable { int my_mutable = 0; int operator()() { // Not const return my_mutable++; } }; โปรดทราบว่าmutable_callableมีไม่ใช่operator()สมาชิกที่แก้ไขตัวแปรสมาชิก ..... ตอนนี้สมมติว่าฉันสร้างstd::functionประเภทของฉัน: std::function&lt;int()&gt; foo = mutable_callable{}; ตอนนี้ฉันสามารถทำสิ่งนี้: void invoke(std::function&lt;int()&gt; const&amp; z) { z(); } int main() { invoke(foo); // foo changed.....oops } ตอนนี้เท่าที่ผมสามารถบอกได้std::functions operator()เป็นconstตาม: https://en.cppreference.com/w/cpp/utility/functional/function/operator () ดังนั้นความรู้สึกของฉันคือคุณไม่ควรทำสิ่งนี้ ..... แต่จากนั้นดูที่: …

1
span สามารถเป็น constexpr ได้หรือไม่
Constructor ของ std :: span ทั้งหมดได้รับการประกาศให้เป็น constexpr แต่ฉันไม่สามารถทำให้พวกมันทำงานในบริบทของ constexpr ได้ การไม่แสดงข้อคิดเห็น constexpr ด้านล่างใด ๆ จะส่งผลให้เกิดข้อผิดพลาดในการรวบรวม #include &lt;array&gt; #include &lt;span&gt; int main() { constexpr int carray[3] = { 0, 1, 2 }; constexpr std::array&lt;int, 3&gt; array{ 0, 1, 2 }; using S = std::span&lt;const int, 3&gt;; /*constexpr*/ S span1{ array.data(), 3 …
11 c++  constexpr  c++20 

1
ทำไมพื้นที่จัดเก็บสำหรับฐานที่ว่างเปล่าซ้ำซ้อนไม่ทับซ้อนกันด้วยตัวชี้ vtable
ลองพิจารณาตัวอย่างนี้: #include &lt;iostream&gt; int main() { struct A {}; struct B : A {}; struct C : A, B {}; std::cout &lt;&lt; sizeof(A) &lt;&lt; '\n'; // 1 std::cout &lt;&lt; sizeof(B) &lt;&lt; '\n'; // 1 std::cout &lt;&lt; sizeof(C) &lt;&lt; '\n'; // 2, because of a duplicate base struct E : A …
11 c++ 

5
ฉันสามารถกำหนดความยาวของอาร์เรย์โดยใช้ค่าคงที่ดังนั้นทำไม int d [b] จึงไม่ทำงาน
int a = 5; const int b = a, c = 4; int e[a]; int d[b]; int f[c]; คำจำกัดความของf[c]ถูกต้อง ตัวแปรbยังเป็นค่าคงที่intแต่คอมไพเลอร์ให้ฉันข้อผิดพลาด"การแสดงออกต้องมีค่าคงที่"int d[b]สำหรับบรรทัด อะไรคือความแตกต่างระหว่างbและc?
11 c++ 

5
C ++ การมอบหมายแบบสามภาคของแลมบ์ดา
ความคิดใดที่ว่าทำไมข้อมูลโค้ดต่อไปนี้ไม่ได้รวบรวม มันบ่นกับข้อผิดพลาด "ข้อผิดพลาด: ตัวถูกดำเนินการหรือไม่: มีประเภทที่แตกต่างกัน" auto lambda1 = [&amp;](T&amp; arg) { ... }; auto lambda2 = [&amp;](T&amp; arg) { ... }; auto lambda = condition ? lambda1 : lambda2;

6
ช่วงไร้เดียงสาที่ใช้สำหรับลูปไม่ทำงาน
ต่อไปนี้ไม่ได้รวบรวม: #include &lt;iostream&gt; int main() { int a{},b{},c{},d{}; for (auto&amp; s : {a, b, c, d}) { s = 1; } std::cout &lt;&lt; a &lt;&lt; std::endl; return 0; } ลองใช้กับ godbolt ข้อผิดพลาดของคอมไพเลอร์คือ: error: assignment of read-only reference 's' ตอนนี้ในกรณีของฉันจริงรายการทำจากตัวแปรสมาชิกในชั้นเรียน ทีนี้มันไม่ได้ผลเพราะนิพจน์กลายเป็นinitializer_list&lt;int&gt;สิ่งที่คัดลอก a, b, c และ d - ดังนั้นจึงไม่อนุญาตให้ทำการดัดแปลง คำถามของฉันคือสองเท่า: มีแรงจูงใจเบื้องหลังที่ไม่ยอมให้เขียนช่วงสำหรับลูปด้วยวิธีนี้หรือไม่? เช่น. …

2
การโทรไปแลมบ์ดานั้นไม่ชัดเจนแม้จะระบุประเภทการคืนอย่างชัดเจน
ฟังก์ชั่นโอเวอร์โหลดควรใช้ทั้งฟังก์ชั่นในเนื่องจากประเภทของแลมบ์ดานั้นสามารถนำกลับมาใช้ใหม่ได้std::function(โปรดแก้ไขให้ฉันถ้าฉันผิด) คำถามคือ: ทำไมมีข้อผิดพลาดในการคอมไพล์ด้านล่าง กำหนดไว้หรือไม่ ( [&amp;]() -&gt; Type {}) โปรดทราบว่าสำหรับวิธีแก้ปัญหาปัจจุบันของฉันฉันต้องการการดักจับโดยอ้างอิงนั่นคือสาเหตุที่รหัสประกอบด้วยตรรกะสำหรับมัน ตัวอย่างต่อไปนี้อธิบายถึงปัญหา: #include &lt;iostream&gt; #include &lt;string&gt; #include &lt;functional&gt; void do_some(std::function&lt;void(int)&gt; thing) { thing(5); } void do_some(std::function&lt;bool(int)&gt; thing) { if (thing(10)) { std::cout &lt;&lt; "it's true!" &lt;&lt; std::endl; } } int main() { int local_to_be_modified = 0; do_some( [&amp;](int in) { local_to_be_modified …

5
กำลังจับวัตถุที่สร้างขึ้นใหม่โดย const อ้างอิงพฤติกรรมที่ไม่ได้กำหนด
ต่อไปนี้เป็นตัวอย่าง (contrived) หรือไม่หรือเป็นพฤติกรรมที่ไม่ได้กำหนดไว้: // undefined behavior? const auto&amp; c = SomeClass{}; // use c in code later const auto&amp; v = c.GetSomeVariable();

1
เทมเพลตตัวแปรสามารถส่งผ่านเป็นอาร์กิวเมนต์เท็มเพลตเทมเพลตได้หรือไม่
ตัวอย่างที่ไร้สาระดังต่อไปนี้ไม่ได้รวบรวม แต่มีวิธีอื่นในการส่งแม่แบบตัวแปรเป็นอาร์กิวเมนต์แม่แบบแม่แบบหรือไม่ template&lt;typename T&gt; constexpr auto zero = T{0}; template&lt;typename T, template&lt;typename&gt; auto VariableTemplate&gt; constexpr auto add_one() { return VariableTemplate&lt;T&gt; + T{1}; } int main() { return add_one&lt;int, zero&gt;(); } ลองใช้ Compiler Explorer

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