4

テンプレートクラスのメンバー関数をいつ呼び出すか知りたいです。定義はどこで生成されますか? 例えば:

template <class T>
class A{
     public:
     A(){cout << "A<T>::A() " << endl;}
     void f(){cout << "A<T>::f() " << endl;}
};

int main(){
A<int> ob; // Time t1
ob.f();    // Time t2

}

ポイント1ポイント2A<int>でテンプレートクラスがどのように見えるか知りたい

ケース 1 :
時間 t1:

 class A<int>{
    public:
    A(){cout << "A<T>::A()" << endl;} // A() body is defined inline
    void f(); // becasue I didn't call A<int>::f yet so there is just a declaration
    };

時間 t1

  class A<int>{
   public:
   A(){cout << "A<T>::A()" << endl;} // A() body is defined inline
   void f(){cout << "A<T>::f()" << endl;} // f() is defined inline
   };

ケース 1 :
時間 t1

class A<int>{
public:
A();
void f();
};

A<int>::A(){cout << "A<T>::A()" << endl;} // this is not inline

時刻 t2

  class A<int>{
    public:
    A();
    void f();
    };

A<int>::A(){cout << "A<T>::A()" << endl;} // this is not inline
void A<int>::f(){cout << "A<T>::f() " << endl;}// this is not inline

では、2 つのケースのどちらが正しいのでしょうか?

4

1 に答える 1

4

ケース1でもケース2でもありません。「定義はどこで生成されますか」という質問は、実際には意味がありません。おそらく、「クラスメンバー関数のインスタンス化のポイントはどこですか」という意味です。その場合、答えは、それらが使用される場所です。したがって、コンストラクターは次の行でインスタンス化されます。

A<int> ob; // Time t1

.. そしてf()、この行でインスタンス化されます:

ob.f();    // Time t2

メンバー関数がクラス内で定義されているかどうかは関係ありません。

関数が使用されていない場合はインスタンス化されませんが、コンパイラは関数内のコードを解析してセマンティック分析を行うことに注意することも重要です。考えてみてください: そこに gobbledygook を置いて、コンパイラがそれを食べることを期待することは明らかにできません。(いくつかのコンパイラー、私が見ている MSVC は、この点で本来よりも緩いです。) この予備分析は、テンプレートのパラメーターが判明する前であっても、フェーズ 1と呼ばれます。型に依存する式での名前検索のように、テンプレート パラメーターが判明するまで、一部の意味解析を行うことはできません。その分析はフェーズ 2で行われ、これらのエラーは、関数がインスタンス化されたとき、つまり使用時にのみ捕捉されます。

関数がインスタンス化されるとはどういう意味ですか? 実際には、構文解析と予備的なセマンティック分析の結果としてコンパイラーが構築した内部表現が、テンプレート パラメーターを提供することによってさらに分析され、その結果がコンパイラーのバックエンドに渡され、コードとして出力されることを意味します。リンカがそれを見つけられるように、関数のマングルされた名前とともにオブジェクトファイル。それが関数が「生成」される場所です。

于 2012-08-25T16:27:27.783 に答える