質問: new cal(array, 5); c->show(); cout << c->getmax() << endl; cout << c->getmin()<< endl; } ``` 結果として、プログラムは実行できなかった。 エラーは、未解決の外部シンボルが4つあると出たが、なにが未解決か自分ではわからなかった。 ちなみに、実行前の各ファイルには、エラーは出ていない。 追加して、sample.cpp ファイルでの、各関数の定義部分で、このtemplateを毎回入れる書き方も正しいのか。。。 詳しい方で、ぜひ教えていただきたいです。
回答: こんにちは。 それは、実はテンプレートの最初の罠です。 コンパイラはsample.cppをコンパイルしている時は、sample.cppの情報だけを使ってコンパイルします。 つまり、main.cppの情報を持ちません。main.cppではテンプレートを使う際にテンプレートの仮引数に型を指定していますが、どのような型を指定しているのかsample.cppをコンパイルしている時のコンパイラは知らないのです。(知るための仕組みがない。) sample.cppで定義されているクラス・テンプレートのメンバ関数をコンパイルする際には、知っている範囲の「テンプレート仮引数に指定された型」を当てはめますので、sample.cppでテンプレートを実体化しない限り、クラス・テンプレートのメンバ関数はコンパイルされません。 その結果、main.cppから呼び出しているクラス・テンプレートのメンバ関数の実体が存在していないので、リンク・エラーになります。 1つの対策は、sample.cppでクラス・テンプレートcalを明示的に実体化することです。 【蛇足ですが】 テンプレートの実体化はインスタンス化と呼ばれることもあります。 ご存知かもしれませんがオブジェクト指向では「クラスのインスタンス」という表現もあります。 この2つの「インスタンス」という用語は全く無関係な2つのものについて、同じ呼び方をしているので要注意です。(意味的にはどちらとも正しい表現ですが、混乱しやすいです。)