1

以下が機能するのはなぜですか?:

template<typename T> class example {
public:
    T val;
    example() {val=0;}
    example operator+(example ob) {
        example temp;
        temp.val = val+ob.val;
        return temp;
    }
};

int main() {
    example<int> a;
    a+a;
    return 0;
}

コンパイルを見ていなかったら、演算子のオーバーロードは次のようになっているはずだったと思います。

example<T> operator+(example<T> ob {
    example<T> temp;
    temp.val = val+ob.val;
    return temp;
}

また、メインで以下を変更しようとしました:

example<int> a;

に:

example a;

しかし、「...テンプレート引数がありません...」というエラーが発生しました。私の推測では、クラス定義内で、コンパイラは例を例として扱います。しかし、これは推測であり、どこにも確認できなかったので、ここで質問しようと思いました.

4

3 に答える 3

2

はい、テンプレート定義の内部にいる場合は、テンプレート引数を省略できます (ただし、たとえば、main はテンプレート定義の外部にあるため、省略できません)。

省略した場合、引数は現在のインスタンス化の引数に置き換えられます。つまり、テンプレートを としてインスタンス化すると、テンプレート定義内のテンプレート引数なしexample<int>のすべての出現は、そのインスタンス化のためにに置き換えられます。exampleexample<int>

標準から(C++ 11、強調鉱山):

(14.6.2.1/1) 名前は、現在のインスタンス化を 参照します。

—クラステンプレート、クラステンプレートのネストされたクラス、クラステンプレートのメンバー、またはクラステンプレートのネストされたクラスのメンバーの定義では、クラステンプレートの注入されたクラス名 (条項 9)またはネストされたクラス、
[...]

いくつかのセクションの後、標準はこの例を示しています。

template <class T> class A {
  A*    p1;     // A is the current instantiation
  A<T>* p2;     // A<T> is the current instantiation

  /*...*/
};
于 2013-01-09T03:15:41.520 に答える
2

それはinjected-class-name(9p2から)のせいです:

クラス名は、クラス名が表示された直後に宣言されているスコープに挿入されます。class-name は、クラス自体のスコープにも挿入されます。これは、 注入されたクラス名として知られています。

および 14.6.1p1 から:

通常の (非テンプレート) クラスと同様に、クラス テンプレートには注入されたクラス名 (条項 9) があります。注入されたクラス名は、テンプレート名または型名として使用できます。template-argument-list と一緒に使用する場合、テンプレート template-parameter の template-argument として使用する場合、またはフレンド クラス テンプレート宣言の精巧な型指定子の最終識別子として使用する場合は、クラス テンプレート自体を参照します。 . それ以外の場合は、テンプレート名の後に <> で囲まれたクラス テンプレートのテンプレート パラメータが続きます。

注入されたクラス名はexample<T>、短縮バージョンを許可するクラス自体の内部を参照します。

于 2013-01-09T03:17:39.597 に答える
1

あなたの質問を正しく理解していれば、はい、クラス定義内で、各関数をクラステンプレートパラメーターのテンプレートにする必要はありません。

実際、クラス外で関数を定義する必要がある場合は、以下のようにする必要があります。

template<typename T>
example<T> example<T>::operator+(example<T> ob) {

psconst example<T>& ob不要なコピーを減らすために引数をに変更する必要があります。

于 2013-01-09T03:16:01.443 に答える