การเชื่อมโยงแบบมีโครงสร้างบน const

รหัสต่อไปนี้ควรจะคอมไพล์หรือไม่

#include <type_traits>

void foo() {
  const std::pair<int, int> x = {1, 2};

  auto [a, b] = x;

  static_assert(std::is_const_v<decltype(a)>);
  static_assert(std::is_const_v<decltype(b)>);
}

นี่เป็นข้อบกพร่องของ MSVC หรือไม่

มาตรฐานไม่ได้ตรงไปตรงมาที่นี่ (ฉันได้ดูอย่างรวดเร็ว) แต่เมื่อพิจารณากฎสำหรับ auto ฉันคิดว่า a และ b ควรถูกคัดลอกโดยละทิ้ง cv-qualifier


person BiagioF    schedule 24.03.2019    source แหล่งที่มา


คำตอบ (2)


รหัสต่อไปนี้ควรจะคอมไพล์หรือไม่

มันไม่ใช่. นี่เป็นจุดบกพร่องของ MSVC

การประกาศการเชื่อมโยงที่มีโครงสร้าง แนะนำชื่อใหม่ (สำหรับข้อกำหนดเท่านั้น) e ซึ่งมีการประกาศดังนี้:

auto e = x;

ประเภทของ e เรียกว่า E และเนื่องจากตัวเริ่มต้นมีลักษณะคล้ายทูเพิล ประเภทของการเชื่อมโยงจึงถูกกำหนดโดย tuple_element_t<i, E>. ในกรณีนี้ E คือ pair<int, int> ดังนั้นทั้งสองประเภทจึงเป็นเพียง int กฎสำหรับ decltype ของการเชื่อมโยงที่มีโครงสร้างคือการให้ ประเภทอ้างอิง ดังนั้น decltype(a) และ decltype(b) จึงเป็นทั้ง int

ส่วนสำคัญที่นี่คือ a และ b (การเชื่อมโยงที่มีโครงสร้าง) มาจากตัวแปรที่ประดิษฐ์ขึ้น (e) และ ไม่ใช่ ตัวเริ่มต้น (x) e ไม่ใช่ const เพราะคุณเพิ่งประกาศเป็น auto สิ่งที่เรากำลังทำคือการคัดลอก x จากนั้นจึงรวมเข้ากับสำเนานี้ (ไม่ใช่-const)

person Barry    schedule 24.03.2019

การยืนยันแบบคงที่ในโค้ดของคุณ ควร ล้มเหลว ทำไม เนื่องจากรหัสของคุณโดยพื้นฐานแล้วจะเหมือนกับกรณีของ:

#include <type_traits>

void foo() {
  const int x_1 = 1;
  const int x_2 = 2;

  auto a = x_1;
  auto b = x_2;

  static_assert(std::is_const_v<decltype(a)>);
  static_assert(std::is_const_v<decltype(b)>);
}

ซึ่ง ล้มเหลวบน MSVC เช่นกัน

ในภาษา C++ ประเภทของนิพจน์จะลดลงเมื่อได้รับมอบหมาย: auto เห็น int ไม่ใช่ const int การเชื่อมโยงแบบมีโครงสร้างช่วยให้คุณทำการเชื่อมโยง auto มากกว่าครั้งละรายการได้

... และความจริงที่ว่า MSVC ไม่ได้ล้มเหลวในการยืนยันในโค้ดของคุณดูเหมือนจะเป็นข้อบกพร่อง

person einpoklum    schedule 24.03.2019