Mengapa static_cast diperlukan dalam implementasi gcc dari is_nothrow_constructible?


11

Diambil dari implementasi GCC type_traitsmengapa static_castdiperlukan di sini?

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>()))> {};

Inkonsistensi itu memang tampak aneh
— Lightness Races di Orbit

4
Anda harus mengajukan pertanyaan seperti ini di milis libstdc ++ yang relevan
— Lightness Races di Orbit

Jawaban:


12

Suatu tipe bukan merupakan konstruksi dari daftar argumen jika deklarasi variabel yang ditemukan

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

akan terbentuk dengan baik dan diketahui tidak melemparkan pengecualian . Dalam kasus argumen jamak, ini setara (modulo noexcept destructibility, lihat LWG 2116 ) untuk pembentukan yang baik dan bukan dari ekspresi konversi tipe

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

Namun dalam kasus argumen tunggal ekspresi T(declval<Args>())diperlakukan sebagai cast-expression , yang dapat memanggil const_castdanreinterpret_cast ; penggunaan eksplisit static_castmengembalikan kesetaraan ke bentuk deklarasi.

Sebagai contoh nyata , pertimbangkan jenis-jenisnya:

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

Di sini, static_castdari B constke ke D&&harus menggunakan operator konversi, tetapi ekspresi pemain dapat memintas operator konversi dan begitu pula kecuali. Jadi mengabaikan static_castakan memberikan hasil yang salah is_nothrow_constructible<D&&, B const>.


Jadi static_castitu diperlukan agar ungkapan itu selalu diperlakukan sebagai direct initializationbukan sebagai cast expression?
— João Pires

1
@ JoãoPires ya, itu benar. Ini masih tidak persis apa yang disyaratkan oleh standar karena tidak mungkin untuk menguji kecuali konsep deklarasi menggunakan noexceptoperator, tetapi jauh lebih dekat.
— ecatmur

Terima kasih untuk bantuannya! : D
— João Pires
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.