2017-10-22 4 views
14

これはstd::threadコンストラクタは(Visual Studioの2015を使用して)宣言した方法です:_Fn_Argsに関するstd :: threadコンストラクタの3番目のテンプレートパラメータの目的は何ですか?

template<class _Fn, 
class... _Args, 
class = typename enable_if< 
    !is_same<typename decay<_Fn>::type, thread>::value>::type> 
explicit thread(_Fn&& _Fx, _Args&&... _Ax) 

ませ質問は、しかし、その第三class = ...は完全に私が混乱しません。それは何をするのですか、それはどのように機能し、それは何のためですか?

+3

'_Fn'型が' std :: thread'の場合にこのコンストラクタを無効にしています。私はそれがコピーコンストラクタであいまいなコールエラーを避けるためだと思う。 –

答えて

16

これは、SFINAEを使用して条件付きで過負荷を有効にする例です。

最初の引数の型がstd::threadの場合、このオーバーロードはオーバーロードの解決には考慮しないでください。

C++標準ヘッダーの生ソースは、を読むことを意図しないことに注意してください。または、を模倣するつもりはありません。 C++コンパイラの実装者は、標準ヘッダーの実装で多くのことを行うことができます。そのうちの少なくとも1つは、_で始まる変数を開始し、その後に大文字が続きます(ユーザーコードで禁止されています)。

_Fnstd::threadの場合はデフォルトの引数の型、同じものへの参照、またはcvを変更したものへの参照を調べます。

typename enable_if< 
!is_same<typename decay<_Fn>::type, thread>::value>::type> 

decay<_Fn>::typeストリップの参照とcv資格。また、関数への参照を関数へのポインタと配列への参照へのポインタを最初の要素へのポインタに変換しますが、ここでは重要ではありません。

_Fnthread&であるとします。私はevalulateます:

typename enable_if< 
!is_same<typename decay<thread&>::type, thread>::value>::type> 
typename enable_if< 
!is_same<thread, thread>::value>::type> 
typename enable_if< 
!true>::type> 
typename enable_if< 
false>::type> 
/* substitution failure occurs */> 

enable_if<B>::typeBtrueある場合にのみ存在します。 _Fnがスレッドの場合はfalseであるため、オーバーロード解決時に置換エラーが発生します。

SFINAEは、置換エラーはエラーではなく、コンパイラが不平を言わずに単にこのオーバーロードを考慮から削除するという意味です。そして、代わりにthread(thread const&)(私は=delete edと思われる)コンストラクタが見つかりました。

5

第3の名前のないテンプレートパラメータには、ムーブコンストラクタを呼び出すときの外乱を避けるために、のテンプレートを使用してSFINAEconstructor of std::threadの次の要件を満たすデフォルト値があります。

std::decay_t<Function>std::threadと同じタイプの場合、このコンストラクタは過負荷解決に関与しません。

関連する問題