• ベストアンサー

c++におけるtemplateについて

c++の自作templateを関数宣言部と関数定義部とで、ファイルを分割する事を考えているのですが、エラーが出てtemplateをincludeすることが出来ないでいます。 例えば、 <ファイル:test.H> #ifndef test_H #define test_H #include <iostream> template<class T> class test { private: int row_, col_; public: test( int , int ); }; #endif <ファイル test.C> #include "test.H" template<class T> test<T>::test(int a, int b) :row_(a), col_(b) { std::cout << "コンストラクター" << std::endl; } <ファイル main.C> #include "test.H" #include<iostream> int main() { test a( 3, 3) return 0; } のようにtemplateファイルを分割した場合、 undefined reference to `test<double>::test(int, int)' collect2: ld returned 1 exit status のようなエラーがでます。 書籍:新c++言語入門・シニア編(下)の29章には「export」を関数定義部に付ければ良いような記述がありましたが、エラーを解決することが出来ませんでした。 main.Cにて、test.Cをインクルードするとこの問題を回避することが出来るのですが・・・。 そもそもtemplateは上記のように宣言部と定義部とを別々のファイルにすることはできないのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

今の時点で export をサポートしているコンパイラなんて, ほとんど存在しないんじゃないかなぁ. 少なくとも gcc はサポートしていないはず. 昔, つまり今の GCC が EGCS と呼ばれていた時代には, 「特定の template をインスタンス化するソースファイル」を吐くようにリンカを改造するという方針で処理した例がありました.

carnot
質問者

お礼

exportはをサポートしたコンパイラは殆ど存在しないんですね。ご回答いただき、ありがとうございました。

その他の回答 (1)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.2

そもそもtemplateにしたいのは関数ですか?クラスですか? 質問は関数のように聞こえますが、サンプルはクラスだし。。。 質問から何がやりたいのか、 いまいち読み取れないのでもう一度自分がやりたいことを 整理してみては?

参考URL:
http://next1.cc.it-hiroshima.ac.jp/CPPPUBLISH/node14.html
carnot
質問者

補足

コメントをいただき、ありがとうございます。 クラスをtemplateにしたいと考えています。よろしくおねがいします。

関連するQ&A

  • templateのエラー

    すいません、C++始めたばっかりなのですが、 以下のようなエラーが出て困っています。 ClusteringMain.obj : error LNK2001: 外部シンボル ""public: void __thiscall File2Array<double>::disp(void)" (?disp@?$File2Array@N@@$$FQAEXXZ)" は未解決です。 どなたかご教授ください。 環境はWindows XP, Visual Studio.NET 以下はソースです。 --------ClusteringMain.cpp------------ #include < iostream > #include"File2Array.h" using namespace std; int main() { cout << "Hello world" << endl; File2Array<double> test; test.disp(); return 0; } ---------File2Array.cpp----------------- #include"File2Array.h" template <class Type> void File2Array<Type>::disp(void) { cout << "aaaaa" << endl; } ---------File2Array.h------------------- #include<iostream> #include<fstream> using namespace std; #ifndef FILE2ARRAY_H #define FILE2ARRAY_H 1 template <class Type> class File2Array { private: Type var; public: void disp(void); }; #endif // #define FILE2ARRAY_H 1

  • c++ , template , ファイル分割 , 助けてください...

    //-----------------coord.h------------- template <class type> class coord { type v[3]; public: coord(void); void Show(void); }; //-----------------main.cpp------------ #include<iostream> #include"coord.h" using namespace std; int main(void) { coord<double> ob; ob.Show(); return 0; } //----------------------coord.cpp----------- #include<iostream> #include"coord.h" using namespace std; template <class type> coord<type>::coord(void) { v[0]=v[1]=v[2]=0; } template <class type> void coord<type>::Show(void) { cout << "hello" << endl; } 同一フォルダ内に上記のファイルが 3 つあります. つまり上の 3 つのファイルを分割してコンパイルさせたいです. この状態で...MS-DOSプロンプトからコンパイルします. C:\test>bcc32 -c coord.cpp Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland coord.cpp: C:\test>bcc32 -c main.cpp Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland main.cpp: C:\test>bcc32 -emain main.obj coord.obj Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Error: 外部シンボル 'coord<double>::coord<double>()' が未解決(C:\USERS\TAITO\PR OG\CPP\TEST\MAIN.OBJ が参照) Error: 外部シンボル 'coord<double>::Show()' が未解決(C:\USERS\TAITO\PROG\CPP\TE ST\MAIN.OBJ が参照) すると, このようなエラー文が出てしまい 実行可能ファイルができません. コンパイラはbccです. 原因が全く分かりません. 助けてください... ちなみに, 分割せずにコンパイルすると通ります. 自分は c 言語での分割コンパイル経験はあるので それをそのまま c++ 言語でも用いているのですが, 何か変えなければならないのでしょうか?

  • テンプレートを使用した時のbcc32とclの違い

    c++を勉強していてわからない事があり、質問させていただきたいと思います。 c++でテンプレートを使ったクラスを以下のように作りました。 //test.h template <class T> class Test { public: Test(); T m_X; }; template <class T> Test<T>::Test<T>() //<<<実際のファイルではここが10行目です { m_X = 10; } //test.cpp #include <iostream.h> #include "Test.h" void main() { Test<int> t; cout << t.m_X << endl; } これをVC++6.0のコンパイラclでは問題なくコンパイルできるのですが、Borland C++ Compailerのbcc32でコンパイルすると、「エラー E2040 Test.h 10: 宣言が正しく終了していない」とのエラーメッセージがでます。なぜ、clでは問題なくコンパイルできるのにbcc32ではコンパイルできないのでしょうか。 ご存知の方、教えていただけないでしょうか。よろしくお願いします。

  • std::stringの継承

    #include <iostream> #include <string> class test : public std::string{ }; int main() { test tmp; tmp = "aaa"; } tmp = "aaa";ですが test::operator =(char *) が定義されていないとでますが何故なんでしょうか? string(basic_string)でoperator=が定義されていると思うのですが、 演算子の定義は継承されないのでしょうか。

  • C++の話です。

    C++の話です。 静的メンバ変数としてクラスを宣言した場合、デストラクタが呼ばれていないようなのですが、呼ぶ方法はありませんか? できれば「new」「delete」を使わずできると理想的です。 分かる方教えていただけると助かります。 以下、サンプルコードです。 「デストラクタが呼ばれました」と出力されない上、デバッガを使って試してみましたが、やはり呼ばれていないようです。 #include<iostream> class Test{   public:     ~Test(){       std::cout<<"デストラクタが呼ばれました"<<std::endl;     } }; class A{   private:     static Test T; }; int main(){   A a;   return 0; }

  • 名前空間でビルドエラー(LNK2005)

    C++の名前空間について勉強しています。 ソースを組んでビルドしようとしたところ、以下のようなエラーが表示されました。 > error LNK2005 "int test::count" は既に main.obj で定義されています。 > fatal error LNK1169: 1つ以上の複数回定義されているシンボルが見つかりました。 変数が多重定義(?)されているというエラーであることはわかるのですが、 その対処法が分からず困っています・・・。 わかる方がいればアドバイスください。 よろしくお願いします。 --------------------------------------- ○main.cpp #include "ns.h" int main(){  test::hoge(); } ○ns.h #pragma once namespace test {  int count;  void hoge(); } ○ns.cpp #include <iostream> #include "ns.h" void test::hoge(){  std::cout << "hoge()が呼ばれた" << test::count++ << "回目" << std::endl; }

  • c++11での文字列リテラルの特殊化について

    c++11言語でのテンプレート部分特殊化についての質問です。 コメントアウト部分は出力結果です template<class T> struct VT { static const int type = 1;}; template<class T,int N> struct VT< T[N] > { static const int type = 2;}; template<class T,int N> struct VT< const T[N] > { static const int type = 3;}; template<class T> struct VT< T* > { static const int type = 4;}; template<class T> struct VT< const T*const > { static const int type = 5;}; #include<iostream> #include<typeinfo> int main(){ std::cout<<"A:"<< VT< char >::type << std::endl; // A:1 std::cout<<"B:"<< VT< char[10] >::type << std::endl; // B:2 std::cout<<"C:"<< VT< char* >::type << std::endl; // C:4 std::cout<<"D:"<< VT< char const [1] >::type << std::endl; // D:3 std::cout<<"E:"<< VT< decltype("") >::type << std::endl; // E:1 std::cout<<"G:"<< typeid( char const [1] ).name() << std::endl;// G:char const [1] std::cout<<"H:"<< typeid( "" ).name() << std::endl;// H:char const [1] } 型名を直接記述したD,G、文字列リテラルを記述したE,H。 コンパイラ毎の差はあれど、GとHの型名は同じものが表示されます。 ですが、[D:3] [E:1]と値は違い、別の特殊化テンプレートが使われています。 この部分が分かりません。 また、配列リテラル、文字列リテラルに対し部分特殊化テンプレートを宣言する方法などありましたら、ご教示お願いします。

  • Visual C++ Toolkitでcppをコンパイルすると・・

    最近質問が多くてすみません。 一応調べてみましたが、同じような質問が既存ならば警告お願いします。 #include <iostream> int main(){ return 0; } これだけのファイルを、例えばtest.cppとして保存します。そして cl test.cpp とすると、ぶわーっと警告(warning)がでて、しかしtest.exeができあがります。 警告内容がかなり長いので、そのうちの1つを載せます。 C:\Program Files\Microsoft Visual C++ Toolkit 2003\include\stdexcept(39) : see reference to class template instantiat ion 'std::basic_string<_Elem,_Traits,_Ax>' being compiled with [ _Elem=char, _Traits=std::char_traits<char>, _Ax=std::allocator<char> ] 意味がわかりません!! ちなみに、bccでは警告なしにコンパイルできます。

  • 6行ソースをコンパイル可能にしてください

    std::fflush(stdout); という所が間違っているんだと思いますが#include <iostream>は#include <iostream.h>にせずにコンパイルしたいです。 #include <iostream> int main(){ std::cout << "h\n"; std::fflush(stdout); return 0; }

  • 【C++】複素数で配列を使いたい

    昨日QNo.3714177で「複素数complex.hがおかしいのでしょうか?」 と言うタイトルで質問させて頂いた、C言語初心者です。 お世話になっております。 今日一日中やっており、C++も少しは理解できるようになったぞっと思った矢先、またまた、問題が発生しました。 複素数の中で、配列を使おうとするとエラーが発生します。 ソースは以下の通りです。上段に私が書いたもの、下段に前回の質問時に教えて頂き、動いたものを記載しております。 どこが間違えているのか教えて頂きたく思います。 よろしくお願い致します。 ============================================================================================================ #include <iostream> #include <iomanip> #include <complex> using namespace std; int main () { int i; for (i=0; i<3; i++) { std::complex <double> Z[i] (i,i); std::cout << "Z[" << i << "]= " << Z[i] << "\n"; } return 0; } //ここより下のみでは動きます。 #if0 #include <iostream> #include <complex> int main() { std::complex<double> x(1.2, 3.4); std::complex<double> y(5.6, 7.8); std::cout << "x = " << x <<"\n"; std::cout << "x = " << y <<"\n"; } #endif ============================================================================================================ Borland C++ 5.6 for Win32 Copyright (c) 1993, 2002 Borland keisan.cpp: エラー E2313 keisna.cpp 11: 定数式が必要(関数 main() ) エラー E2034 keisna.cpp 11: 'int' 型は 'complex<double>[1]' 型に変換できない(関数 main() ) エラー E2293 keisna.cpp 11: ) が必要(関数 main() ) *** 3 errors in Compile ***

専門家に質問してみよう