我需要在我的模板化单例类中使用std :: call_once,但目前下面的示例代码没有编译:
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();
}
所以需要帮助理解如何在这里正确使用std :: call_once。
答案 0 :(得分:3)
您的问题是&LifeTrackerHelper::SetLongevity<T>
是一个期望unique_ptr
和unsigned int
的函数指针,但它只获得一个参数。虽然实际函数具有第二个参数的默认值,但在由函数指针调用时它需要两个参数。
您可以通过传递另一个参数来修复它:
std::call_once(flag, &LifeTrackerHelper::SetLongevity<T>, ptr, 0);
或者你可以把它包装成lambda:
std::call_once(flag, [](std::unique_ptr<T>& p){ return LifeTrackerHelper::SetLongevity<T>(p); }, ptr);
根据cppreference,在C ++ 17之前,call_once
的参数将被复制或移动。到目前为止,我还没有通过unique_ptr
传递任何错误,但在其上使用std::ref
可能是明智之举。