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>()))> {};
João Pires
sumber
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>.

ecatmur
sumber
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