เหตุใดจึงต้องมี static_cast ในการใช้งาน gcc ของ is_nothrow_constructible


11

นำมาจากการใช้ GCC type_traitsว่าทำไมจึงstatic_castต้องมีที่นี่

template <typename _Tp, typename... _Args>
struct __is_nt_constructible_impl
    : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))> {};

template <typename _Tp, typename _Arg>
struct __is_nt_constructible_impl<_Tp, _Arg>
    : public integral_constant<bool,
                               // Why is `static_cast` needed here?
                               noexcept(static_cast<_Tp>(declval<_Arg>()))> {};

ความไม่ลงรอยกันนั้นดูแปลก ๆ
การแข่ง Lightness ใน Orbit

4
คุณควรถามคำถามเช่นนี้ในรายชื่อผู้รับจดหมาย libstdc ++ ที่เกี่ยวข้อง
Lightness Races ใน Orbit

คำตอบ:


12

ชนิดที่ไม่สามารถสร้างขึ้นได้จากรายการอาร์กิวเมนต์หากประกาศตัวแปรที่คิดค้น

T t(declval<Args>()...);

จะได้รับรูปแบบที่ดีและเป็นที่รู้จักกันไม่ข้อยกเว้นจากเส้นข้าง ในกรณีที่เป็นพหูพจน์นี่เป็นสิ่งที่เท่าเทียมกัน (โมดูโล noexcept destructibility ดูLWG 2116 ) กับรูปแบบที่ดีและไม่เกิดการแสดงออกของประเภทการแปลง

T(declval<Args>()...)

อย่างไรก็ตามในกรณีอาร์กิวเมนต์เดียวการแสดงออกT(declval<Args>())จะถือว่าเป็นการแสดงออกซึ่งสามารถเรียกconst_castและreinterpret_cast ; การใช้อย่างชัดเจนของการstatic_castคืนค่าความเท่าเทียมกันกับแบบฟอร์มการประกาศ

เป็นตัวอย่างที่เป็นรูปธรรมพิจารณาประเภท:

struct D;
struct B { operator D&&() const; };
struct D : B {};

ต่อไปนี้เป็นstatic_castจากB constถึงD&&ต้องใช้ตัวดำเนินการแปลง แต่นิพจน์เพี้ยนสามารถข้ามตัวดำเนินการแปลงได้ดังนั้นจึงไม่มีข้อยกเว้น ดังนั้นถนัดจะให้ผลที่ไม่ถูกต้องสำหรับstatic_castis_nothrow_constructible<D&&, B const>


ดังนั้นstatic_castเป็นสิ่งจำเป็นเพื่อให้การแสดงออกได้รับการปฏิบัติเสมอเป็นdirect initializationแทนที่จะเป็นcast expression?
João Pires

1
@ JoãoPiresใช่ถูกต้อง มันยังไม่ตรงตามที่มาตรฐานกำหนดเพราะมันเป็นไปไม่ได้ที่จะทดสอบข้อยกเว้นของการประกาศโดยใช้noexceptโอเปอเรเตอร์ แต่มันใกล้กว่ามาก
ecatmur

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