
今、ベクトル計算を簡単にするクラスを作ってみようとしています。
//vector3.h
template<class TT> class vector3{
public:
enum{NUM=3};
TT x[NUM];
void set(const TT *vv)void set(const TT *vv){
int i;
for(i=0;i<NUM;i++){
x[i]=vv[i];
}
}
};
のように、set関数をクラスの中に書いていると問題無いのですが、以下のように、
//vector3.h
template<class TT> class vector3{
public:
enum{NUM=3};
TT x[NUM];
void set(const TT *vv);
};
//test.cpp
#include"vector3.h"
template<class TT> void vector3<TT>::set(const TT *vv){
int i;
for(i=0;i<NUM;i++){
x[i]=vv[i];
}
}
と、cppファイルの中に書き換えると以下のようにエラーが出るようになります。
error LNK2001: 外部シンボル ""public: void __thiscall vector3<double>::set(double const *)" (?set@?$vector3@N@@QAEXPBN@Z)" は未解決です。
fatal error LNK1120: 外部参照 1 が未解決です。
これはいったい何故なのでしょうか?
使用しているのはVisualC++2008ExpressEditionです
宜しくお願いします。
No.2ベストアンサー
- 回答日時:
コンパイル時、test.cpp で実装されたメンバ・テンプレートの
テンプレート引数 TT の具体的な型が不明なのでコンパイルしようが
ありません。コンパイルされませんからリンク時にも見つかりません。
解答有り難うございます。
一つ疑問に思ったのですが、includeはファイルを引っ付けるだけって言う認識なのですが、templateの有効範囲はincludeとか関係なく、単一のファイルのみの有効範囲ということになっているのでしょうか?
また、templateは、「template<class T>」と書いた後の一番最初の関数もしくは、classの「{}」の範囲のみで有効と言うことでしょうか?
templateの名前空間の有効範囲がよく分からないので宜しくお願いします。
No.3
- 回答日時:
> includeはファイルを引っ付けるだけって言う認識なのですが、
その通りです。
> templateの有効範囲はincludeとか関係なく、
> 単一のファイルのみの有効範囲ということになっているのでしょうか?
有効範囲とは何のことを言っていますか?
「どこから使える(呼べる)か」ということなら、どこからでも使えます。
質問にあったコードが良い例になっています。
コンパイルエラーにはなっていませんね。
vector3<double>を使うのに問題はなく、
vector<double>の「実体が存在しない」ため
リンク・エラーになっています。
No.1
- 回答日時:
こんにちは。
メンバ関数の中身もヘッダに置くか、test.cppをインクルードするかしないと無理なのではないでしょうか。
http://ja.wikipedia.org/wiki/C%2B%2B
exportと言うキーワードが在るのですが、VC2008でも使えなかったような気がします。
後、vector3が継承しておらず、コンストラクタ系を書いていなければ、
vector3<int> v = {0,1,2};
と言った具合で、固定配列の初期化と同じ書き方が出来ると思います。
更にネタとして、
template<class TT, int NUM> class vector3{
public:
TT x[NUM];
void set(const TT *vv);
};
と書いて、
vector3<int, 3> v = {0,1,2};
と言った書き方も出来ます。
解答有り難うございます。
色々調べ回った結果、テンプレートの明示的なインスタンスの生成てことをやっておくとうまくいくらしいですね。
http://www.fides.dti.ne.jp/~oka-t/cpplab-templat …
まあ、それ以前に良く考えれば、テンプレートはコンパイル時に処理される静的なものなのだから、ファイル分割何かしたらテンプレートが定義されていなくなるのだから、コンパイルできなくて当然ですよね。
>>template<class TT, int NUM>
テンプレートって値も指定できるんですね。全然知りませんでした^^;
あと、このクラスは
typedef vector3<double> vector3d;
みたいな感じで定義して使おうかなって考えてます。
どうも有り難うございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
静的でないメンバ関数の呼び出...
-
コンパイルエラー: LNK2001
-
C言語 extern について
-
const_castのつかいどころを教...
-
戻り値を返す関数の前に(void)...
-
VC++でGetKeyboardStateがうま...
-
多重定義が起きている?--lnk20...
-
【VC++6.0】イベントハンドラ関...
-
関数名の名前の衝突について。
-
C++にてtemplateで受け取った任...
-
既定のコンストラクタがありま...
-
DLLの関数呼び出しで引数がある...
-
gcc: incompatible pointer type
-
【gcc・cygwin】multiple defin...
-
H8 3664Fのプログラム
-
C++ 静的クラスの役割が分からない
-
ウインドウの移動禁止
-
(void)0 はどんな意味ですか
-
int main()、void main()、void...
-
Delphiの定数とローカル変数の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
【gcc・cygwin】multiple defin...
-
多重定義が起きている?--lnk20...
-
静的でないメンバ関数の呼び出...
-
C++にてtemplateで受け取った任...
-
const_castのつかいどころを教...
-
既定のコンストラクタがありま...
-
戻り値を返す関数の前に(void)...
-
C# KeyDownイベントでショート...
-
int main()、void main()、void...
-
C# Controls.Addで動的に配置し...
-
(void)0 はどんな意味ですか
-
C#でラジオボタンを設定に記録...
-
VC++でGetKeyboardStateがうま...
-
gcc: incompatible pointer type
-
クラス内で、親ではない他のク...
-
ウインドウの移動禁止
-
void*型の配列について
-
ドラッグしたときにマウスカー...
-
_beginthreadにて発生するコン...
-
C#でテンキーの操作は可能でし...
おすすめ情報