これは明示的には述べていませんが、実際のコードでは、A
の.hファイルに特殊化を宣言していないと思います。したがって、別のコンパイル単位にA.h
が含まれていた場合、コンパイラはWriteNative()
の特殊化に気づいていませんでした。専門の宣言を追加する(すなわち、それをインライン化する必要がない)同じファイルに定義を含めることなく、問題を修正する必要があります
class A {
public:
template<typename T> int WriteNative(const T) {
printf("here?\n")
return 0;
}
template<typename D>
void doit() {
if (WriteNative<double>(1)) {
printf("A\n");
} else {
printf("B\n");
}
}
};
template<> int A::WriteNative(const double);
次の3つのファイルA.h
、A.cpp
を使用して問題を再現することができ、 main.cpp
はA.h
が含まれている場合にインライン化が最適化中に発生した、と-O0
してコンパイルするとき、何のインライン化が発生していないので、WriteNative()
がA.cpp
で定義に対してリンクがあったとき、それは専門の気づかないようA.cpp
は、専門の定義が含まれているとmain.cpp
、 。
編集: これはanswerを参照してください。これは、仕様がこの動作が正しい理由を説明するものです。
14.7.3 [temp.expl.spec]:
テンプレート、メンバーテンプレートまたはクラステンプレートのメンバーは が明示的に特化されていた場合、その専門分野は、前 に宣言されなければならない
6 /そのような使用が発生する のすべての翻訳単位で 暗黙的なインスタンス化が行われるような特殊化の最初の使用。診断は必要ありません。プログラム が明示的な特殊化の定義を提供せず、 暗黙のインスタンス化が行われるか、またはメンバーが仮想メンバー 関数であるような方法で特殊化が使用されるか、診断は必要ありません。 暗黙的なインスタンス化は、明示されていても定義されていない明示的な 特殊化に対しては決して生成されません。
私の解決策は、特殊な定義をインライン展開することです:http://stackoverflow.com/questions/4445654/multiple-definition-of-template-specialization-when-using-different-objects –