5

テンプレート型パラメーターを指定してクラス テンプレートのインスタンスを作成するとき、私は疑問に思っていました。
1)呼び出されていない関数が開始されないのはなぜですか? .
2)使用しようとするまでコンパイルされませんか?
3)この動作の背後にあるロジックは何ですか?

template <class T>
class cat{
public:

T a;
void show(){
   cout << a[0];
}
void hello(){
   cout << "hello() get called \n";
}
}; 

int main(){
cat<int> ob1; // I know that show() did not get instatiated, otherwise I will get an    error since a is an int
ob1.hello();

 }
4

4 に答える 4

6

テンプレートはコードではありません。実際のコードを作成するために使用されるパターンです。パラメータを指定するまでテンプレートは完成しないため、事前にコードを作成することはできません。特定のテンプレート パラメーター セットを使用して関数を呼び出さない場合、コードは生成されません。

于 2012-06-28T20:35:14.430 に答える
3

もう少し装飾すると、これは通常ダックタイピングと呼ばれ、要点は、あるテンプレートタイプでインスタンス化されたときに一部のメンバー関数が適用される「クラスパターン」を記述できることです。 2 番目のテンプレート タイプを使用し、実際に呼び出してコンパイルする必要があるものだけを必要とすることで、一般的な操作になる操作のコードを大幅に減らすことができます。

すべてのメンバー関数をコンパイルする必要がないことにより、実際にコンパイルされる関数の静的型チェックのすべての利点を得ることができます。

たとえば、あなたが持っていたと想像してください:

  template <typename E> 
  class myContainer {

      // Imagine that constructors, setup functions, etc. were here

      void sort();   // this function might make sense only if E has an operator< defined

      E max();   // compute the max element, again only makes sense with a operator<

      E getElement(int i);  // return the ith element

      E transmogrify();  // perhaps this operation only makes sense on vectors
  };

次に、あなたは持っています

  // sort() and getElement() makes total sense on this, but not transmogrify()
  myContainer<int> mci;         

  // sort and max might not be needed, but getElement() and transmogrify() might
  myContainer<vector<double>> mcvd;        
于 2012-06-28T21:01:00.903 に答える
3

クラス全体をインスタンス化すると、無効なコードが生成される可能性があります。

あなたはいつもそれを望んでいるわけではありません。

なんで?C++ では、「X、Y、および Z が true の場合にのみこのコードをコンパイルする」と言うのは難しい(場合によっては、私の知る限り、完全に不可能です) ためです。

たとえば、「埋め込みオブジェクトをコピーできる場合、私のコピー コンストラクターのみ」とはどのように言えますか? 私の知る限り、あなたはできません。

そのため、実際に呼び出さない限りコンパイルしないようにしました。

于 2012-06-28T20:32:38.347 に答える
2

cat<int>::show()呼び出すことはないため、コードは生成されません。呼び出した場合、コンパイルエラーが発生します。呼び出されることのないテンプレート関数は存在しません。

テンプレートは、テスト置換メカニズムにすぎません。これはそれらを非常に強力にします。あなたはプログラマーとして、無効になる他の何かcat<int>を決して呼び出したり呼び出したりしないことを知って作成したいと思うかもしれません。show()コンパイラはあなたがそうしたかどうかを知らせてくれるので、うまくいきます。

それで、あなたの質問が「なぜそれがこのように機能するのか」であるならば、私はあなたに「なぜそうではないのか」と尋ねますか?それはデザインの選択です。この選択により、テンプレートタイプを安全に使用しながら、コードの他の部分から利益を得ることができます。害は何ですか?また、生成するコードも少なくなります。これは良いことですよね?

于 2012-06-28T20:32:08.610 に答える