2

Primer C++ > Adventures in Functions > Templates > Explicit Specialization を読んでいます。

Explicit Specialization の理由/用途を示すために、ケースが示されています。任意の型 (int、double、struct など) を交換できる swap テンプレート関数を検討してください (コードは明らかだと思うので、ここに記述する必要はありません)。

ただし、特定の構造体 (ジョブと呼ばれる) の 2 つのメンバーのみを交換し、残りのメンバーはそのままにしておく必要があります。別の定義が必要になるため、明示的な専門化を作成する必要があります。

同じセクションに次のステートメントがあります。「特殊化は通常のテンプレートをオーバーライドし、非テンプレート関数は両方をオーバーライドします。」その使用のために(通常の)関数を作成しないのはなぜですか?次に、通常の/非テンプレートがテンプレートをオーバーライドしますか?

私の解決策が正しい場合、明示的な特殊化の良い例は何ですか?

4

3 に答える 3

5

明示的な特殊化のユースケースの1つは、実際の関数で何らかの変更が発生したときに通常の関数がスキップされないようにすることtemplateです。理解するには、以下の例を参照してください。

template<typename T1, typename T2>
void foo(T1 o1, T2 o2)  // template function
{}
void foo(int o1, int o2) // regular function overloaded
{}

今までは大丈夫です。しばらくして、次の定義を変更する必要がありますtemplate<> foo()

template<typename T1, typename T2, typename T3> // new parameter added
void foo(T1 o1, T2 o2, T3 o3)  // template function
{}

foo()それに応じてすべての呼び出しを変更しましたが、通常のオーバーロードされた関数を変更するのを見逃した/混乱foo()させました。そして、それは災害です!コンパイルはうまくいき、通常の呼び出しはサイレントにに置き換えられるためtemplate<> foo()、これは望ましくありません。

さて、次のような明示的な専門分野がありましたか?

template<>
void foo(int o1, int o2) // explicit specialization
{}

その場合、その関数は、パラメーターが一致しないためにコンパイルエラーが発生し、対応する変更を通知します。

他の使用法または(違い)は、明示的に特殊化された関数を、複数のシンボルのリンクエラーを気にすることなくヘッダーファイルにインクルードできることです。明示的な特殊化にも独自の欠点があることに注意してください。ただし、デモにはその良い面があります。

于 2011-06-20T04:47:53.493 に答える
1

その使用のために(通常の)関数を作成しないのはなぜですか?次に、通常の/非テンプレートがテンプレートをオーバーライドしますか?

もちろん、明示的な関数テンプレートの特殊化の代わりに、通常の関数オーバーロードを使用することもできます。ただし、(テンプレート パラメーターを指定して) 関数テンプレートを明示的に使用する場合、通常の関数オーバーロードは使用されません。

例:

関数テンプレートがあります:

template< class T >
void foo( T& x, const T& y )
{
...
}

次に、関数のオーバーロードを指定した場合:

void foo( double& x, const double& y )
{
....
}

このようなコードでは:

template< class T >
void some_function( T& x )
{
    T y;
    ......
    foo<T>( x, y );
}

関数のオーバーロードvoid foo( double& x, const double& y )は使用されません。

しかし、関数テンプレートの特殊化を指定すると

template<>
void foo<double>( double& x, const double& y )
{
....
}

次にsome_function、あなたが電話した場合、あなたの専門分野を使用します

double x;

some_function(x);

どこか。

于 2011-06-20T10:16:02.027 に答える
0

1 つの例として、標準関数は特殊化されている場合がありますが、オーバーロードされていない場合があります。もう 1 つの例は、型が推定不可能であり、明示的なテンプレート引数でそれらを呼び出す既存のコードがある場合です。その場合、オーバーロードは価値がありません。

于 2011-06-20T10:35:26.677 に答える