Вы можете использовать неявное преобразование указателя в bool:
SingletonClass* getInstance() {
if (instance.load()) {
std::lock_guard<std::mutex> lock (m);
if(instance.load()){
instance.store(new SingletonClass());
}
}
return instance;
}
Просмотреть его онлайн
Обратите внимание, что неявное преобразование из std::atomic<SingletonClass*>
в SingletonClass*
возможно, но неоднозначно в этом контексте. Кроме того, само присвоение неоднозначно, поэтому был добавлен вызов store()
.
Однако, возможно, решение более простое - зачем вообще нужен std::atomic
? Вы уже блокируете доступ к сохраненному указателю, поэтому вы в безопасности:
#include <mutex>
class SingletonClass {
public:
SingletonClass* getInstance() {
std::lock_guard<std::mutex> lock (m);
if (instance == NULL) {
instance = new SingletonClass();
}
return instance;
}
private:
SingletonClass() = default;
~SingletonClass() = default;
static SingletonClass* instance;
static std::mutex m;
};
std::atomic
используется для доступа без блокировки (или, по крайней мере, с доступом к скрытой блокировке). Я не могу придумать причину использовать их вместе на макушке головы.
Мьютекс здесь в значительной степени необходим - вы хотите заблокировать целую функцию как критическую секцию, иначе два потока могут создать два одноэлементные объекты, и один будет протекать.