1 つのメンバー関数を持つ単純なクラス テンプレートを定義しました。これは、追加の (明示的な) 特殊化を使用してクラスの外部で定義され、クラスの外部でも定義されます。すべてが 1 つのヘッダーファイルに含まれています。このヘッダーを複数の翻訳単位に含めると、One-Definition-Rule が原因でリンカー エラーが発生します。
// Header with a template
template <class T>
class TestClass
{
public:
TestClass() {};
~TestClass() {};
bool MemberFunction();
};
template <class T>
bool TestClass<T>::MemberFunction()
{
return true;
}
template <>
bool TestClass<double>::MemberFunction()
{
return true;
};
これまでのところすべて順調です。しかし、メンバー関数の定義をクラス本体内に配置すると、リンカー エラーがなくなり、関数をさまざまな翻訳単位で使用できるようになります。
// Header with a template
template <class T>
class TestClass
{
public:
TestClass() {};
~TestClass() {};
bool MemberFunction()
{
return true;
}
};
template <>
bool TestClass<double>::MemberFunction()
{
return true;
};
私の質問は、なぜそのように機能するのですか? 私は MSVC 2012 を使用しています。ODR には、私が最初に考えた理由であるテンプレートに関するいくつかの例外があります。しかし、クラスの内外の「ベース」関数の定義は、ここで違いを生みます。