Reputation: 1921
I need to use std::call_once in my templatized singleton class but currently below sample code is not compiling :
std::once_flag flag;
class LifeTrackerHelper
{
public:
template<class T>
inline static int SetLongevity(std::unique_ptr<T>& pobj,unsigned int longevity = 0)
{
return 0;
}
};
template<class T>
class Singleton
{
public:
inline static T* getInstance()
{
static std::unique_ptr<T> ptr(new T());
std::call_once(flag,&LifeTrackerHelper::SetLongevity<T>,ptr);
//static int i = LifeTrackerHelper::SetLongevity<T>(ptr);
// if call_once is commented and above line uncommented this will work
return ptr.get();
}
};
class Test
{
public:
void fun()
{
std::cout<<"Having fun...."<<std::endl;
}
};
int main()
{
Singleton<Test>::getInstance()->fun();
}
So need help in understanding how to properly use std::call_once here.
Upvotes: 3
Views: 566
Reputation: 4637
Your problem is &LifeTrackerHelper::SetLongevity<T>
is a function pointer expecting a unique_ptr
and an unsigned int
, but it only gets the one argument. While the actual function has a default value for the second argument, it needs both arguments when called by a function pointer.
You can fix it by passing another argument:
std::call_once(flag, &LifeTrackerHelper::SetLongevity<T>, ptr, 0);
Or you can wrap it in a lambda:
std::call_once(flag, [](std::unique_ptr<T>& p){ return LifeTrackerHelper::SetLongevity<T>(p); }, ptr);
According to cppreference, before C++17 the arguments to call_once
will be copied or moved. So far, I haven't gotten any errors passing a unique_ptr
, but it might be wise to use std::ref
on it.
Upvotes: 3