9

次の構成を検討してください。

//! Templated singleton.
/*!
    Template wrapper enforcing the singleton behavior.
*/
template <class T>
class TSingleton
{
private:    
    //! Singleton instance pointer.
    static T* instance;
    //! private constructor.
    TSingleton() { }
    //! private empty copy constructor.
    TSingleton(const TSingleton<T>& sourceObject) {}

public:
    //! Static singleton instance getter.
    static T* GetInstance()
    {
        if (instance == 0)
            instance = new T();
        return instance;
    }

};

template <class T> T* TSingleton<T>::instance = 0;

このテンプレート クラスと静的インスタンスの定義は、同じヘッダー ファイルに記述されます。非テンプレート クラスの場合、インスタンス static member に対して複数のシンボルが定義されているため、リンク時エラーが発生します。これがテンプレートでも発生するのは直感的に思えるため、定義を分離して .cpp ファイルに入れる必要があります。ただし、テンプレートは通常、ヘッダーのようなファイルで宣言および定義されます。この構文がテンプレート クラスに対して有効で機能することを可能にするのは何ですか?

これに関するウィキペディアのリンクがありますが、テンプレートクラスの場合に何が起こるかについて明確な説明はありません。

4

1 に答える 1

13

これは、[basic.def.odr]/5テンプレートの複製が明示的に許可されているため機能します。

クラス型 (条項 9)、列挙型 (7.2)、外部リンケージを持つインライン関数 (7.1.2)、クラス テンプレート (条項 14)、非静的関数テンプレート (14.5.6) の複数の定義が存在する可能性があります。 、クラス テンプレートの静的データ メンバー (14.5.1.3)、クラス テンプレートのメンバー関数 (14.5.1.1)、または一部のテンプレート パラメータが指定されていないテンプレートの特殊化 (14.7、14.5.5)定義が別の翻訳単位に表示され、定義が次の要件を満たしていることが条件です。...

要件は非常に長いため、ここでは重複しませんが、本質的には、重複する各定義は同一でなければならないと述べています (そうでない場合、プログラムは未定義の動作をします)。

于 2012-08-31T11:17:14.050 に答える