2012-02-15 3 views
3

基本的な配列ラッパーテンプレートクラスを.oファイルにコンパイルしようとしていますが、動的ライブラリを作成する方法を理解しようとしています。ただし、ソースをg ++で空のオブジェクトファイルが生成される

g++ -std=c++0x -c array.cpp 

でコンパイルすると、結果ファイルは約650バイトにすぎません。 -std = C++ 0Xフラグなしでコンパイルされたとき、彼らがそうであるように、私は、NMでファイルを調べ、それが含まれるシンボルのみがC++ 11のコンパイルの特徴であると思わ

00000001 r _ZStL13allocator_arg 
00000000 r _ZStL19piecewise_construct 

た見出さ行った。

プログラムのテストコードをコンパイルしようとすると、すべてのコマンドで

g++ -std=c++0x -o tester tester.cpp array.cpp 

がarray.cppにすべてのためのリンカエラーを生成しますが、それ以外はきれいにコンパイルされます。

私は正に、これで何が起こっているのか分かりません。 array.cppとarray.hppの内容は、コンパイル方法ではなく、コード自体で問題があると思われる場合に投稿できます。

+1

インスタンス化されていないテンプレートをコンパイルしようとしていますか? – ildjarn

+1

テンプレートはコード生成ツールほどのコードではありません。実際のコードのみがコンパイルされます。 –

+0

これは、配列としてtester.cppでインスタンス化されます。私はtester.cppなしでコンパイルしようとしました。なぜなら、.cpp内のすべての関数にかかわらず、2番目の(時系列に最初の)コンパイルコマンドでリンカーエラーが発生していた理由を理解するためです。 –

答えて

8

これは正常です。テンプレートは、をインスタンス化したときにのみコードになります。あなたはテンプレートを提供しただけです。コンパイラはテンプレートをコンパイルしていますが、実際の型をテンプレート引数として埋め込んだテンプレートの特定のインスタンスを生成する理由はありません。

その後、コンパイラは、テンプレートタイプを使用する他のソースファイルをコンパイルします。それもインスタンス化の原因にはなりません。コンパイラには、テンプレートのインスタンスが他の場所にあることが予想されることを伝えるだけです。コンパイラはオブジェクトファイルにそのことを記録します。次に、リンカーは、コンパイラーが見つけたはずの定義を探しますが、失敗します。

なぜなら、ヘッダの宣言とともにインラインでテンプレートの定義を提供することを常にお勧めします。このようにして、コンパイラはテンプレートを使用すると見て、ヘッダで見た定義を使ってすぐにテンプレートをインスタンス化できます。複数のソースファイルでテンプレートを使用すると、テンプレートを複数回インスタンス化する複数の定義で終わる可能性がありますが、これは許可されており、リンカーはそれをどのように処理するかを知っています。

代わりに、array.cppファイルのテンプレートを明示的にインスタンス化することもできますが、テンプレートメンバーをインラインで定義する方が簡単です。

+0

非常に参考になりました。これを見つけるのに多くの時間を費やしました。 – Tagar

+0

テンプレートのインライン宣言に宣言を付ける良い方法の例を挙げることができますか? –

+1

[ドキュメントの主な例](http:// stackoverflow。com/documentation/c%2b%2b/460/templates/3999/basic-class-template#t = 201702250241383624287)、@Warren。実装はすぐに宣言に続いた。 (同じファイル内の 'main'の存在はここでは無関係です。) –

0

array.cppにテンプレートのみが含まれている場合は、別々にコンパイルしないでください。おそらくarray.hppという名前になります。

関連する問題