3

次のようなものを検討してください...

template<typename T>
class Vector {
  ...
  bool operator==( const Vector<float> &rhs ) {
    // compare and return
  }

  bool operator==( const Vector<T> &rhs ) {
    // compare and return
  }
  ...
 };

特殊化が非特殊化バージョンよりも上にあることに注意してください。特殊化されたバージョンを非特殊化されたバージョンのVector<float>に配置した場合、 == 比較は意図したとおりに機能しますか? 何らかの理由で、このシナリオで特殊化を下に置くと、コンパイラがヘッダーを調べたときに、最初にデフォルトが表示され、それが機能することを確認し、それを使用することを読んだことを覚えていると思います。

4

2 に答える 2

7

あなたのコード例は特殊化されていませんが、オーバーロードしています。関数は C++ で認識される前に宣言する必要があるため、順序は重要です (ただし、コード内では重要ではありません)。そのため、あるオーバーロードが別のオーバーロードを呼び出す場合、または間にある別の関数がオーバーロード セットを呼び出す場合、呼び出しが望ましくない場所で終了する可能性があります。サンプルコードは有効で一般的です。

何らかの理由で、このシナリオで特殊化を下に置くと、コンパイラがヘッダーを調べたときに、最初にデフォルトが表示され、それが機能することを確認し、それを使用することを読んだことを覚えていると思います。

あなたは次のルールを考えています

テンプレート、メンバー テンプレート、またはクラス テンプレートのメンバーが明示的に特殊化されている場合、その特殊化は、そのような使用が発生するすべての翻訳単位で、暗黙的なインスタンス化を発生させる特殊化の最初の使用の前に宣言する必要があります。 ; 診断は必要ありません。

ここで、専門分野に関する標準の陽気な言葉を引用せずにはいられません。

上と下で指定されているように、明示的な特殊化宣言の相対的な位置付けと翻訳単位でのそれらのインスタンス化のポイントに従って、プログラムが整形式であるかどうかに影響を与える可能性があります。専門化を記述するときは、その場所に注意してください。またはそれをコンパイルすることは、その自己犠牲を燃やすような試練になるでしょう.

于 2010-08-21T01:38:13.047 に答える
-3

書かれているように、私はあなたに誤りがあると信じています。operator== を特殊化していません。オーバーロードしています。そのようなテンプレート パラメーターをオーバーロードすることはできません。

メソッドが自由関数である場合、それを特殊化できます。例えば

template <typename T>
void Foo(Vector<T> x) {
   std::cout << "x" << std::endl;
}
template <>
void Foo(Vector<float> y) {
   std::cout << "y" << std::endl;
}

...
Vector<int> intVec;
Vector<float> floatVec;
Foo(intVec); //prints x
Foo(floatVec); //prints y

この場合、 で Foo をVector<float>呼び出すと、特殊化されたバージョンが呼び出されます。

順序はある程度重要です。まず第一に、コンパイラは、特殊化されていない形式が利用可能な場合、常に特殊化を優先します。その後、コンパイラは各関数を順番にインスタンス化しようとします。正常にコンパイルできる場合は、その特殊化が使用されます。それができない場合は、次のものに進みます。この原則は、Substitution Failure is not an Error (SFINAE) と呼ばれます。 http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_errorには、より詳細な説明があります。

于 2010-08-20T22:44:51.067 に答える