gccのis_nothrow_constructibleの実装でstatic_castが必要なのはなぜですか?


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

その矛盾は奇妙に思われます
オービットの軽量レース

4
あなたは、関連のlibstdc ++メーリングリスト上でこのような質問をする必要があります
軌道上での明度レース

回答:


12

発明された変数宣言の場合、型は引数リストから構築できません

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

だろう、よく形成され、例外をスローしないことが知られています。複数の引数の場合、これは型変換式の整形およびnothrow と同等です(破壊可能性を除けば、モジュロnoexcept、LWG 2116を参照)。

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

ただし、単一引数の場合、式T(declval<Args>())andを呼び出すことができるcast-expressionとして扱われます。を明示的に使用すると、等価性が宣言フォームに復元されます。const_castreinterpret_caststatic_cast

具体的な例として、種類を考慮してください。

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

ここではstatic_castfrom B constto D&&は変換演算子を使用する必要がありますが、キャスト式は変換演算子をバイパスできるため、例外ではありません。したがって、を省略するstatic_castと、に対して誤った結果が返されis_nothrow_constructible<D&&, B const>ます。


したがって、static_cast式が常にではdirect initializationなくとして扱われるように、が必要cast expressionです。
ジョアン・ピレス

1
@JoãoPiresはい、そうです。noexcept演算子を使用して宣言を除いてnoexexをテストすることはできないので、標準で要求されているものはまだ正確ではありませんが、はるかに近いです。
ecatmur

助けてくれてありがとう!:D
ジョアン・ピレス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.