2017-07-26 19 views
0

externテンプレートを理解しようとしていますが、動作させることができません。私の目標は、コンパイル時間を節約するために、別のコンパイルユニットにFoo<>がある場合、いくつかのインスタンスをコンパイルすることです。私のコードベースでは、テンプレートの引数はenum classなので、理論的に私はコンパイル単位ですべてのインスタンスをコンパイルし、残りのプロジェクトとリンクすることができます。externテンプレートをC++で理解する

:私はこれに沸くメイクファイルを、使用コンパイルのために

//Foo.hpp 
#pragma once 

template <class T> 
struct Foo { 
    Foo(); 
    ~Foo(); 
}; 

extern template struct Foo<int>; 

//Foo.cpp 
#include "Foo.hpp" 

template struct Foo<int>; 

//main.cpp 
#include <iostream> 

#include "Foo.hpp" 

int main(int argc, char **argv) { 
    Foo<int> foo; 

    return 0; 
} 

:ここ

は、私が思い付く少し例です

g++ -c ../Foo.cpp ../main.cpp 
g++ Foo.o main.o 

私はGCC 7.1.1で取得し、打ち鳴らす4.0.1と基本的に同じ出力は、次のとおりです。

main.o: In function `main': 
main.cpp:(.text+0x27): undefined reference to `Foo<int>::Foo()' 
main.cpp:(.text+0x38): undefined reference to `Foo<int>::~Foo()' 

私の主な質問は、なぜFoo<int>::Foo()Foo<int>::~Foo()Foo.oにコンパイルされていませんか?

+1

コンストラクタとデストラクタが何をするのかをコンパイラに知らせるために、何も提供していないからです。彼らは2つの数字を追加しますか? 2つの数字を減算しますか? 「戦争と平和」の言葉の数を数えますか?ピンの先端にある天使の数を数えますか?コンパイラがインスタンスを生成するためには、コンストラクタをどこかに記述する必要があります。 –

答えて

3

コンストラクタとデストラクタはで定義されていないため、どこでもと定義されているため、宣言するだけです。テンプレートをFoo.cppファイルで明示的に正しくインスタンス化しますが、関数はまだ定義されていません。

だけFoo<int>を使用しようとしている場合、あなたは、Foo.cppに明示的にテンプレートをインスタンス化するという事実に

template<typename T> 
Foo<T>::Foo(){...} // or = default 

template<typename T> 
Foo<T>::~Foo(){...} 

と原因をコンストラクタとデストラクタを定義することができますFoo.cppにリンカーが定義を見つけるでしょう。それ以外の場合は、ヘッダファイルに定義を提供する必要があります。

+0

入手しました。私はexternテンプレートに集中していたので、それを見落としています。ありがとうございました。 – OutOfBound

+0

@OutOfBound 'extern template'sの実際の使用法の詳細については、https://stackoverflow.com/q/8130602/3093378も参照してください。 – vsoftco

+0

この例のコードの目的は、 'Foo 'または 'Foo 'のテンプレート関数定義を示すかどうかはわかりません。前者の場合、2つの '::'の前に ''を追加します。後者の場合は 'template <> Foo :: Foo(){...}'が必要で、デストラクタも同様です。 –

関連する問題