コンパイルを高速化するために、C++ extern テンプレートをいじっています。Visual Studio 2012 で の処理が改善されたことに気付きましたがextern template
、まだ問題が見つかっています。次に例を示します。
main.cpp:
#include <iostream>
#include "Calc.h"
using namespace std;
int main(int argc, char** argv)
{
Calc<int> c1;
cout << c1.add(1, 2) << endl;
}
計算時間:
#pragma once
template <class A_Type>
class Calc
{
public:
A_Type add(A_Type x, A_Type y)
{
return x + y;
}
};
extern template class Calc<int>;
通常、テンプレートが 1 回だけインスタンス化されるように、Calc.cppをに含めます。template class Calc<int>;
この例では、Main.cppのみをコンパイルし、失敗することを期待しています。
問題は、Visual Studio 2012 が問題なく上記のコードをコンパイルしてリンクすることです。を尊重していませんextern template
。私が見つけた唯一の解決策は、ヘッダーでこれを行うことです:
計算時間:
#pragma once
template <class A_Type>
class Calc
{
public:
A_Type add(A_Type x, A_Type y);
};
template <class A_Type> A_Type Calc<A_Type>::add(A_Type x, A_Type y)
{
return x + y;
}
extern template class Calc<int>;
ヘッダーがこのようなものである場合、Visual Studio はリンクに失敗します (予想どおり、 の定義が欠落していると不平を言っていますCalc<int>::add
)。ただし、g++ 4.6.3はこれらの例のいずれもリンクできません。
誰が正しいですか?クラス内の関数のプロトタイプと定義の両方が同じヘッダー ファイルで指定されている場合、実際に違いはありますか? 「短い形式」のCalc.hを指定して、Visual Studio 2012 (および gcc) で期待どおりに失敗させる方法はありますか?