Я пытаюсь использовать шаблон Singleton с std::call_once, но при компиляции не удалось выполнить вывод шаблона.
template<typename T>
class Singleton_4
{
public:
template<typename...Args>
static void create(Args&&...args) {
tPtr = new T(std::forward<Args>(args)...);
}
public:
template<typename...Args>
static T* instance(Args&&...args) {
std::call_once(flag, &Singleton_4::create, std::forward<Args>(args)...);
return tPtr;
}
public:
Singleton_4() = default;
Singleton_4(const Singleton_4&) = delete;
Singleton_4(Singleton_4&&) = delete;
Singleton_4& operator=(const Singleton_4&) = delete;
Singleton_4& operator=(Singleton_4&&) = delete;
private:
inline static T* tPtr;
inline static std::once_flag flag;
};
Я хочу знать, что случилось и как решить эту проблему.
Решение: просто измените &Singleton_4::create
на &Singleton_4::create<Args...>
Рабочая демо
Это работает хорошо! Спасибо за ответ искренне!
Пожалуйста :)
Проблема в том, что create
— это шаблон функции, а не реальная функция. И мы не можем взять адрес шаблона. Вместо этого нам нужно взять адрес созданной функции из шаблона функции.
Это можно сделать, явно указав аргумент шаблона, как показано ниже:
Решение
template<typename...Args>
static T* instance(Args&&...args) {
//------------------------------------------------vvvvvvv---->passed Args explicitly to make it clear that we are taking address of an instantiation
std::call_once(flag, &Singleton_4::create<Args...>, std::forward<Args>(args)...);
return tPtr;
}
create
— это шаблон функции, а не реальная функция. Вам нужно взять адрес его экземпляра вместо адреса шаблона функции.