2016-06-16 13 views
4

テンプレートのパラメータリストでclass = std::enbale_if<condition, type>::typeカップル回を遭遇しましたが、私はstd::enable_if<B,T>::typeが何をしているのかよく分かりませんが、class =は何ですか?私はclass type_name = typeを知っていますが、なぜclass =にタイプ名がないのですか?私はそれをいつ使うのですか?テンプレートタイプの差し引き

編集:この例here

template <class T, class U, class = typename enable_if 
      <is_lvalue_reference<T>::value ? is_lvalue_reference<U>::value : true>::type> 
inline T&& forward(U&& u) 
{ 
    return static_cast<T&&>(u); 
} 
+0

コンパイルエラーです。これはそのままです。コンパイルエラーはさておき、これは単に名前のないテンプレートパラメータです。 – SergeyA

+1

サンプルを投稿してください。より直接に対応できるようにします。 – vu1p3n0x

+0

私は質問を編集しました –

答えて

3

これはSFINAEです(置換エラーはエラーではありません)。以下は2つの例です。正しいものではないタイプのインスタンス化を禁止するために、structとclassに制約が置かれています。

しかし、どのようなクラス=はわかりませんか?私はクラスtype_name = typeを知っているが、クラス名に型名がないのはなぜですか?私はそれをいつ使うのですか?

これは名前の付いていないテンプレートパラメータタイプですが、このパラメータは不要です(無効な候補を削除するために)オーバーロード中にのみ使用されるため、このパラメータは不要です。実際にそれに名前を付けると、警告が表示されることがあります。

http://coliru.stacked-crooked.com/a/25162a3eb107943f

// Allow only T to be floating type (!! actually static_assert would be preferred here) 
template<class T, 
     class = typename std::enable_if<std::is_floating_point<T>::value>::type> 
struct foo { 

}; 

template <class T, 
      class = typename std::enable_if<std::is_integral<T>::value>::type> 
bool is_even(T i) {return !bool(i%2);} 

int main() 
{ 
    // foo<int> f; //error 
    foo<float> f; //ok 

    //is_even(1.1); //error 
    is_even(1); //ok 

    return 0; 
} 

私は例の上に言わなければならない[編集]

は最高ではありません、それは有益なエラーメッセージを生成することを可能にするようstatic_assertを使用してお奨めすることになります。 SFINAEは、パラメータの検証に使用するのではなく、提供されるタイプに応じて別の実装を選択するために使用してください。

2

からそれは無名のテンプレート型パラメータです。未使用の関数パラメータに変数名を残すことができるように、参照されていないテンプレートパラメータにはパラメータ名を指定することができます。

std::enable_if<...>::typeという特定のケースでは、これはSFINAEの目的でのみ使用されます。具体的には、enable_ifのブール値がfalseの場合、テンプレートパラメータの減算は失敗します。

関連する問題