2

enable_if struct の定義によると:

template<bool B, class T = void>
struct enable_if {};

template<class T>
struct enable_if<true, T> { typedef T type; };

私はどのように疑問に思っています

template<class T>
T foo(T t, typename std::enable_if<std::is_integral<T>::value >::type* = 0) 
{
    return t;
}

特に :

typename std::enable_if<std::is_integral<T>::value >::type

std::is_integral<T>::valueequalの場合、型 T を指定せずに呼び出すことができますtrue。この場合、 std::enable_if の特殊化が呼び出され、この定義にはデフォルトのテンプレート パラメータはありません。

テンプレートパラメータメカニズムを推測するためですか?はいの場合、特殊化定義ではないデフォルトのパラメーターを指定したのはなぜですか?

4

2 に答える 2

2

あなたの質問は少し不可解ですが、私が理解しているように:

...タイプ T を指定せずにどのように呼び出すことができるのか疑問に思っています

  1. そうはなりません。fooおよびテンプレートは、ユーザーが の特定の値を使用してenable_if(暗黙的または明示的に) インスタンス化する必要がある場合にのみインスタンス化されます。Soは常に指定されます。TT

  2. デフォルトのテンプレート パラメータは、「ベース」テンプレート定義でのみ機能します (つまり、特殊化ではありません)。そのため、 の最初の宣言でのみ表示されますenable_if。ただし、それらはすべての特殊化に影響します (基本的に、 をインスタンス化するenable_if<X>と、コンパイラーは基本テンプレートの引数の 1 つが提供されていないことを認識し、すべての特殊化をパラメーター list と一致させようとします<X, void>)。

ところで、2 番目のテンプレート引数は、 とは異なる型を取得するために使用されenable_ifますvoid

std:enable_if<1, int>::type f();

ちょうどでしょうint f()

于 2012-11-13T13:40:59.233 に答える
1

テンプレートの目的は、オーバーロード セットから関数テンプレートenable_if削除することです。それ自体では、コンパイルエラーで非整数型のインスタンス化を拒否することを除いて、あなたの例はあまり役に立ちません。ただし、たとえば逆条件を使用して 2 番目のオーバーロードも記述した場合、実行可能なオーバーロードは 1 つだけであり、あいまいさはfoo(1)ありfoo(1.0)ません。

実際、これについてもう一度考えてみてください: の引数を推測している間foo(1.0)、最初のバージョン (あなたが書いたもの) は実際には誤りです。メンバー型が存在しないから::typeです。ただし、これはハード コンパイラ エラーではなく、いわゆる「置換エラー」にすぎません。これはエラーではありません。テンプレート全体を考慮から除外するだけです。

補足として、デフォルトの引数を使用して、特殊化を明確にするのに役立つenable_ifin classテンプレートの関連する使用法があります。それは何かのように見えますtemplate <typename T, typename = typename std::enable_if<some_condition>::type> ...

于 2012-11-13T13:37:32.450 に答える