Я новичок в шаблонном программировании.При реализации одноэлементного класса с использованием шаблона я обнаружил, что в некоторых случаях (как показано ниже) компоновщик жалуется на ошибку:
undefined reference to `Singleton<Test>::_lock'
Однако, если я изменю следующий оператор
template<> Mutex Singleton<Test>::_lock;
на
template<> Mutex Singleton<Test>::_lock(1);
компилируется и запускается без ошибок.
Может ли кто-нибудь помочь мне и объяснить, почему в приведенном ниже случае сбой компиляции?
#include <iostream>
#include <pthread.h>
class Mutex {
public:
Mutex(){ pthread_mutex_init(&mMutex, NULL); }
Mutex(int dummy){ pthread_mutex_init(&mMutex, NULL); }
~Mutex(){ pthread_mutex_destroy(&mMutex); }
Mutex(const Mutex&) = delete;
Mutex& operator = (const Mutex&) = delete;
int lock(){ return -pthread_mutex_lock(&mMutex); }
void unlock(){ pthread_mutex_unlock(&mMutex); }
// Manages the mutex automatically. It'll be locked when Autolock is
// constructed and released when Autolock goes out of scope.
class Autolock {
public:
explicit Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
~Autolock() { mLock.unlock(); }
private:
Mutex& mLock;
};
private:
pthread_mutex_t mMutex;
};
template <typename T>
class Singleton: {
public:
static T& Instance() {
Mutex::Autolock _l(_lock);
if(nullptr == _instance) {
_instance = new T();
}
return *_instance;
}
virtual ~Singleton(){}
Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
static T* _instance;
static Mutex _lock;
};
class Test: public Singleton<Test> {
public:
void dis() {std::cout << "hi" << std::endl;}
};
template<> Mutex Singleton<Test>::_lock;
template<> Test* Singleton<Test>::_instance(nullptr);
template class Singleton<Test>;
int main()
{
Test::Instance().dis();
return 0;
}