2016-07-04 8 views

答えて

8

より:

変数定義T obj(std::declval<Args>()...); F [I]は他valuefalseで、valuetrueに等しく、十分に形成されています。

template <class...> 
using void_t = void; 

template <class, class T, class... Args> 
struct is_constructible_ : std::false_type {}; 

template <class T, class... Args> 
struct is_constructible_< 
    void_t<decltype(T(std::declval<Args>()...))>, 
T, Args...> : std::true_type {}; 

template <class T, class... Args> 
using is_constructible = is_constructible_<void_t<>, T, Args...>; 

usingフープ:

コードは、例えば、SFINAE技術を用いて行うことができる(C++ 1Z標準ライブラリの一部であると期待される)void_t<>トリックよく形成されているかどうかを確認最初にvoid_t<>引数を配置することです。通常は最後にデフォルトタイプがありますが、その位置はvariadic Argsパックによって保持されます。

<void, T, Args...>でインスタンス化されると、コンパイラはまず特殊化をインスタンス化しようとします。これは、is_constructibleの要件で指定されているように、の内容が意味的に有効である場合、つまりT(std::declval<Args>()...)が正しく実行された場合にのみ成功します。ローカル変数の代わりに一時変数を使用していますが、私の知る限り、ルールは2つの間で変更されません。専門化はstd::true_typeから継承され、truevalueが得られます。

特殊化をインスタンス化できない場合(つまり、T(std::declval<Args>()...)が無効な場合)、コンパイラは常にインスタンス化できる一般的なテンプレートに戻ります。これはstd::false_typeから継承し、falsevalueとなります。

Live on Coliru

より正確な特性は、そのようstd::is_trivially_constructibleとして、その有効性形質の値となるべき表現を作るために言語規則のより高度な知識が必要です。これがstd::is_standard_layoutのように言語の内側から実行不可能であると判明した場合、コンパイラ自体はその値を取り出すための組み込み関数を提供しなければならない。

+0

それは優れた説明だった、ありがとう! – Alex

+0

'T(Arg)'はCスタイルのキャストと等価であるため、 'is_constructible 'は 'true'であるため、これは' std :: is_constructible'と全く同じではありません。 std'はfalseを返します。 –

関連する問題