templateクラスの宣言と定義を、別々のファイルに分けたい

このQ&Aのポイント
  • templateクラスの宣言と定義を別々のファイルに分ける方法について知りたいです。
  • 通常、テンプレートクラスのメンバ関数はインライン展開するべきですが、宣言部と定義部を別々のファイルに分ける方法があれば教えてください。
  • テンプレート変数をクラス内で共有したいため、テンプレート関数ではなくテンプレートクラスで実現したいのですが、インライン関数でなければならないのでしょうか?
回答を見る
  • ベストアンサー

templateクラスの宣言と定義を、別々のファイルに分けたい

こんばんは。 templateを利用したクラスについての質問です。 通常、テンプレートクラスのメンバ関数は、その定義部分をインライン展開するべき、とのことですが… なんとかして宣言部と定義部を別々のファイルに分ける事は出来ないでしょうか? テンプレート変数をクラス内で共有したいため、テンプレート関数ではなく、テンプレートクラスで上記の事を実現したいのです。 「コンパイラによっては、インライン関数でなければならない」という記述を見かけたので、 コンパイラによってはインライン関数でなくても構わないのでしょうか? 開発環境は WindowsXP-SP2 VisualStudio2005-SP1 C++コンソールアプリケーションです。

  • Forte_
  • お礼率75% (214/284)

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

  • ベストアンサー
noname#160244
noname#160244
回答No.2

C++にはexportというキーワードがあって、 それを指定すれば宣言と定義を別々のファイルに書けるみたいですが、 現状ではexportをサポートしているコンパイラは少ないようです。 なお、宣言と定義を同じファイルに書くことをインライン展開とはいいません。

その他の回答 (1)

回答No.1

>「コンパイラによっては、インライン関数でなければならない」という記述を見かけたので、 どこにそんな嘘書いてあったんでしょう。 inlineの必要はありません。 正しくは 「定義はそれを使う利用者側コードと同じ  コンパイルユニットになければならない」 です。

関連するQ&A

  • VB.NETでテンプレート関数・クラス

    VB.NET(.NET2.0ベース)でテンプレートを用いてクラスや関数を定義したいのですが、方法が分かりません。検索してもC#やC++ばかり出てきます。 C#が出てくるのだから、VBでも…と思いましたが、CILに展開される際、型毎に多重宣言でもしているんでしょうか? とりあえず、VB.NETでテンプレートの使い方をご教示頂ければ幸いです。

  • テンプレートクラス内のテンプレートクラス(インナークラス)のメソッドを実装ファイルで定義したい

    現在、ヘッダファイル内で下記のようなクラスを宣言・定義しています。 // test.h template < typename T1 > struct A {   template < typename T2 > struct B   {     B( A const& arg ) { ... }   }; }; テンプレートクラスが入れ子になっていて、Bのコンストラクタが引数としてAを取っています。 しかし現状ではコンパイルがとんでもなく遅くなってしまうので、 Bのコンストラクタは宣言のみとし、別途実装ファイル(test.cpp)に定義を書きたいと思っています。 ところがメソッドのシグネチャをどう書けばよいのか分からなくなってしまいました。 苦し紛れに // test.cpp template < typename T1, typename T2 > A<T1>::B<T2>::B( A<T1> const& arg ) { ... } などと書いてみましたが、違うようです。 解決方法はありますでしょうか? 環境はVC7.1かVC8でコンパイルできればよいです。 よろしくお願いいたします。

  • テンプレートクラスのフレンド関数の宣言

    テンプレートクラスに対して、operator << を定義しようとしてハマってしまったので。 ---- 最終的にできたコードはこんな感じ ---- template<size_t M> class MyContainer; template<size_t N> std::ostream& operator<<( std::ostream& os, MyContainer<N> const& cont ); template<size_t M> class MyContainer {  friend   ostream& operator<< <M>( ostream& , MyContainer<M> const& ); <= ここで「operator<<」としてハマった  public:   MyContainer() { }  private:   void Print_( std::ostream& os ) const {    copy( content_, content_ + M, ostream_iterator<int>( os, "\n" ) );   }  private:   int content_[M]; }; template<size_t N> ostream& operator <<( ostream& os, MyContainer<N> const& cont ) {  cont.Print_( os );  return os; } ------------------------------ テンプレートクラスのfriend関数を宣言する場合に、関数に明示的にテンプレート引数を与えないとテンプレート関数の特殊化だけが friend となるようです。 そういうもんだと言ってしまえばそれまでですが、何故こんな変態的な仕様になってるんでしょう? 特殊化された関数だけをテンプレートクラスのfriend に指定したいような状況が想像できません。

  • templateクラスについて

    先ほど以下のようなプログラムを書いたのですがコンパイルを通すことができません。 //適当なポインタを保持するだけのクラス template <class _type> class hoge { private:   //適当に変数を保持   _type val; public:   //コンストラクタで適当に値をセット   hoge() : val( 0 ){}   //このクラスから唯一ポインタを引っ張ってくる方法   friend _type getVal( const hoge& foo )   {     // そのまま返す     return foo.val;   } }; void func( const hoge<int>& foo ) {   //値を引き出す   getVal( foo ); } void main() {   //実体化   hoge<int> foo;   //値を引き出す   getVal( foo );   //関数の先で値を引き出す   func( foo ); } 上記のようなプログラムを書いたのですが、main関数内でgetValを呼び出す場合はとくに問題ないのですがfunc関数を呼び出してfunc関数内でgetValを呼び出すと error C3861: 'getVal': 識別子が見つかりませんでした error C2365: 'getVal' : 再定義; 以前の定義は '以前は不明な識別子' でした。 コンパイルされたクラスの テンプレート のインスタンス化 'hoge<_type>' の参照を確認してください というエラーが出てしまいます。 func関数の引数を( const hoge<int>& foo )からvoid func( hoge<int> foo )のように参照渡しから実体渡しに変更するとコンパイルが通り、実行もできるのですが、なぜこれでコンパイルが通るのか理由がいまいちよくわかりません。 またやはり、コンストラクタ、デストラクタの問題などから実体渡しより、参照渡しを使いたいのですがどのようにプログラムを書けば今回の問題を解決できますでしょうか。 よろしくおねがいします。 /* VisualStudio2005 AcademicEdition MicroSoft WindowsXP Professional 32bit */

  • ポインタによる包含&ヘッダにincludeしない、 場合でtemplateの定義に…

    class Bの宣言をしているヘッダ中で class A; を、前方宣言し、そのポインタだけを持たせ、ソースファイルのほうにclass Aの中身が分かるように、#includeして、ソースファイルに関数の実装やstatic変数の定義を書いていた、とします。 しかし、templateを使う関数についてはコンパイル時に解決できないといけないので、それだけはヘッダに持ってきました。 その時 includeが一切書かれていない、class Bのヘッダ内において class Aのメンバを参照するようなコードを書いたとき クラス外、クラス内、いずれに書いても 正常にコンパイルできました。 通常の関数では当然無理なので、もともとtemplateがコンパイル時解決を強要するものなのでそういう仕様にしててくれてると考えられますが 1.これは、C++の標準仕様でしょうか?それとも処理系依存でしょうか? あと、templateに関して 2.特殊化ならソースにかけるのは標準仕様でしょうか?それとも処理系依存でしょうか?

  • C++のtemplateクラス前方宣言について教えてください

    C++で、以下のようなコードを書いたのですがコンパイルが通りません。 どのようにコードを修正すればコンパイルを通すことができるでしょうか??教えてください。 template <class _T> class Test; // 上をclass Test<_T>にしてもコンパイルは通りません void main() {   Test<int> hoge; } template <class _T> class Test { public:   _T val;   Test():val(0){}; }; /*! エラー内容: 前方宣言class Test;の場合 'hoge'が未定義のclass'Test<_T>'で使用しています。   with   {     _T=int   } 前方宣言class Test<_T>;の場合 構文エラー:';'が'<'の前にありません。 構文エラー:'<' 'hoge'が未定義のclass 'Test<_T>'で使用しています。 */ 開発環境: VisualStudio2005 AcademicEdition WindowsXP Professional メモリ:2048MB CPU:Core2Duo 1.33GHz よろしくお願いします。

  • クラスのメンバ関数を別ファイルで定義したときのバグ

    C++ においてヘッダファイルで宣言したクラスのメンバ関数を別のソースファイルで定義して、コンパイルするとうまくいきません。エラーは出ないのですが、同名の何もしない関数としてコンパイルされているようなのです。クラスのメンバ関数を宣言したのと同じヘッダに書くとちゃんとコンパイルされます。 どうしてそうなるのか、いまいち原因がわかりません。

  • クラス メンバ関数インライン化

    クラス内でメンバ関数を定義するとインライン関数になると書いてあったのですが、全てクラス内でメンバ関数を定義してはだめなのでしょうか?   クラス外でメンバ関数を定義するメリットを教えてください。 教えてくださいm(_ _ )m

  • ソースファイルの分割について

    a.h クラスの定義 a.cpp クラスのメンバ関数の定義 b.h #include "a.h" クラスの定義 b.cpp クラスのメンバ関数の定義 ----c.cpp---- #include "a.h" #include "b.h" a.hで定義したクラスの宣言 b.hで定義したクラスの宣言 メインの処理 ----------------------------------------- b.cppで定義しているクラスのメンバ関数にて a.cppで定義したクラスのメンバ変数にアクセスしたいのです。 どうするのが一番良いのでしょうか? a.cppにメンバ変数を返すだけの関数を定義してb.cppでc.cppで宣言したa.hのクラスを extern宣言してみたのですがエラーが出てコンパイルが通らないです。

  • クラスの関数へユーザー定義型の引数を渡す(VB6.0)

    お世話になります。 クラスモジュール内へ宣言した関数へユーザー定義型(標準モジュール内でPublicで宣言)の引数を渡すとコンパイルエラーとなってしまいます。 ユーザー定義型を宣言した以外の標準モジュールでは同じ関数は動きますが、Formモジュールでは動きません。 標準モジュールにしかユーザー定義型の引数を渡すことは出来ないのでしょうか??

専門家に質問してみよう