How to use boost::call_once() on a function with arguments

boost, c++, multithreading

Solution

You can bind additional function parameters to a functor object using `boost::bind`. Like this:

Input* input = ???;
boost::call_once(flag, boost::bind(&Singleton::getInstance, input));

You can use `boost::bind` to call non-static member functions as well, by passing the instance of the class on which you want to call the function to `boost::bind`.

class Foo
{
public:
   void func(int) { /* do something */}
};

Foo f;
boost::call_once(flag, boost::bind(&foo::func, &f, 10));

With C++11, you can use `std::bind`, here's another example. `boost::bind` is quite similar.

#include <utility>
#include <functional>
#include <iostream>
#include <string>

void f(int x)
{
   std::cout << "f(" << x << ")\n";
}

void g(int x, const std::string& y)
{
   std::cout << "g(" << x << ", " << y << ")\n";
}


int main()
{
   auto ten = std::bind(&f, 10);
   auto example = std::bind(&g, 20, "Twenty");

   ten();
   example();

   return 0;
}

Problem

I want to use boost::call_once() to achieve a thread-safe lazy-construction singleton scenario, however, the base singleton class has many derived classes thus the getInstance() function takes an argument to determine which derived class to initialize. The code looks like, ``` Singleton * Singleton::getInstance(Input * a) { if (!instance) { instance = buildme(a); //buildme() will return a derived class type based on input a. } return instance; } ``` I want to use `boost::call_once()`, but looks like it can only be used on functions with no arguments `void (*func)()`. If anybody knows about an alternative solution here please help. Thanks. EDIT:: Another question, how to call a non-static member function using `call_once`? I have a non-static `init()` member function of this class, but I couldn't find a correct syntax for calling it using `boost::call_once()`. Or should I make `init()` and everything used in it static? Thanks.

Original source