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;

这个模板类和静态实例的定义写在同一个头文件中。对于非模板类,由于为实例静态成员定义了多个符号,这会导致链接时错误。模板也会发生这种情况似乎很直观,因此必须将定义分开并将其放入 .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 回答