c++ - 如何在带参数的函数上使用 boost::call_once()

标签 c++ multithreading boost

我想使用 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/

相关文章:

c++ - 将 cout 与 basic_string<unsigned char> 一起使用

java - JTextArea 中正在执行写入操作

使用线程和互斥体计算文件中的字符数

java - 我们可以同时从多个线程访问同一个实例的同步方法和非同步方法吗?

c++ - boost::interprocess 互斥锁崩溃而不是等待锁?

c++ - PhysX - 如果使用 GPU,simulate() 永远不会结束

c++ - 进程终止时是否回收了内存?

c++ - 构建后清理 boost 临时文件

c++ - 矩形算法中的多边形?

c++ - 使用相同的 key boost 访问许多 std::maps