我想使用 boost::call_once() 来实现线程安全的惰性构造 然而,单例场景中,单例基类有许多派生类,因此 getInstance() 函数采用一个参数来确定要初始化哪个派生类。代码看起来像,
Singleton * Singleton::getInstance(Input * a) {
if (!instance) {
instance = buildme(a); //buildme() will return a derived class type based on input a.
}
return instance;
}
我想使用 boost::call_once()
,但看起来它只能用于没有参数的函数 void (*func)()
。如果有人知道这里的替代解决方案,请提供帮助。
谢谢。
编辑::
另外一个问题,如何使用call_once
调用非静态成员函数?我有一个此类的非静态 init()
成员函数,但我找不到使用 boost::call_once()
调用它的正确语法。还是我应该将 init()
和其中使用的所有内容设为静态?
谢谢。
最佳答案
C++11 包含 call_once 的实现(受等效的 Boost.Threads 工具启发)。它使用可变参数模板和完美转发来获取任意数量的参数。
#include <mutex>
#include <string>
void only_called_once(int i, std::string const & str) {
// We only get here once.
}
void call_free() {
static std::once_flag once;
std::call_once(once, only_called_once, 42, "The answer");
}
您可以在可调用函数之后传递任意数量的参数,它们都将被完美转发(包括右值/左值、const、volatile 等)。
这也适用于成员函数。您只需传递一个指向对象的指针(可转换为成员函数所属的类型)作为可调用对象之后的第一个参数。
struct bar {
public:
void only_call_once(int i, std::string const & str);
};
void call_member() {
static std::once_flag once;
bar instance;
std::call_once(once, &bar::only_call_once, &instance, 42, "The answer");
}
如果你坚持使用 Boost,那么你可以使用 boost::bind
来达到另一个答案中已经解释过的相同目的。带有 boost::bind
的成员函数的工作方式与上面相同,传递一个成员函数指针和一个实例作为以下参数。
关于c++ - 如何在带参数的函数上使用 boost::call_once(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13793579/