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

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.

C++11 contains an implementation of call_once (inspired by the equivalent Boost.Threads facility). It uses variadic templates and perfect forwarding to take an arbitrary number of arguments.
#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");
}
You can pass an arbitrary number of arguments after the callable and they will all be perfectly forwarded (including r-value/l-value, const, volatile, etc).
This also works for member functions. You just have to pass a pointer to an object (convertible to the type the member function belongs to) as the first argument after the callable.
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");
}
If you are stuck with Boost then you can use boost::bind for the same purpose as has already been explained in another answer. Member functions with boost::bind work the same way as above by passing a member function pointer and an instance as the following parameter.

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;
}

Related

C++ std::bind Function as Parameter Store in Class Variable

I have the following problem. class A implements some routines that should be used on a dataset that is being processed in Class B. That means I'm calling the function start from class A. What I'm doing should be saved in a variable m in class A. So far so good. However, when accessing class variable m it is still on the state when initialized.
To be precise:
#include <iostream>
#include <functional>
class A {
public:
int m;
A() {
m = 100;
}
void start(int value) {
std::cout << "hello there!" << std::endl;
m = value;
}
};
class B {
private:
int m;
public:
void doSomething() {
A a;
doSomething2(std::bind(&A::start,a, std::placeholders::_1));
// access variable m of instance a
std::cout << a.m << std::endl;
}
template <typename Callable>
void doSomething2(Callable f) {
int val = 4444;
f(val);
}
};
main()
{
B b;
b.doSomething();
}
When executing this, I'll get 100 as an output for m. How will I be able to have the changes made by the call of start stored in the class variable? Meaning, storing the value 4444 as in this example? Thanks
Looks like you'll want to make sure that std::bind is using a pointer to the actual class instance you've created. Try changing it to:
// notice I've got '&a' here instead of just 'a'
doSomething2(std::bind(&A::start, &a, std::placeholders::_1));
Without this, I would guess what bind is doing now is making a copy of the a instance and then modifying that one instead of changing it in place.
Bind by default takes arguments by value, in result start() acts on a copy of object a. You have to pass it by reference:
doSomething2(std::bind(&A::start, std::ref(a), std::placeholders::_1));
Possible alternative is to use a lambda expression instead.

Calling function from std::array of function pointers

I can't figure out how to call function pointer stored in std::array which is member of class.
namespace logic {
class Chance {
std::array<void(logic::Chance::*)(), 15> m_redChances;
};
}
void logic::Chance::redChance1 {
std::cout << "Red chance one\n";
}
logic::Chance::Chance()
{
m_redChances[0] = &Chance::redChance1;
}
It looks fine till now, but when I want to call this function in another member function, nothing seems to work. Only first line compiles, but it doesnt call my function. Rest are giving erros:
logic::Chance::anotherMemberFunction() {
m_redChances[0];
(*m_redChances[0]*)();
(*logic::Chance::m_redChances[0])();
m_redChances[0]();
*m_redChances[0]();
*logic::Chance::m_redChances[0]();
*logic::Chance::m_redChances[0];
*(*m_redChances[0])();
}
operand of "*"must be a pointer type
and
expression precending parentheses of apprent call must have
(pointer-to-) function type
EDIT#
So I tried to use std::function and had to change class design a bit, I want to achieve something like this
struct Foo {
std::array<std::function<void(Foo&)>, 3> funArray;
Foo() {
funArray[0] = &Foo::fun1;
funArray[1] = &Foo::fun2;
}
void fun1() {
std::cout << "fun1\n";
}
void fun2() {
std::cout << "fun2\n";
}
std::function<void(Foo&)> getFunction(int i) {
return funArray[i];
}
};
int main() {
Foo foo;
foo.getFunction(0);
std::cin.get();
}
As you can guess, this isn't calling my function and I again, tried every combination to return this correctly, but cant figure it out, thats the only one that compiles, but does nothing. How can I return a function call of function sotred in std::array by another function? A bit messy, but hope you get what I mean.
std::array<void(logic::Chance::*)(), 15> m_redChances is an array of pointers to a non-static member function of objects of class Chance. Therefore, you need to apply the object where the pointed-to member function is going to be called.
In the statement:
(*logic::Chance::m_redChances[0])();
no object is provided. On which object's data is that call going to be performed?
Considering chance an object of Chance and chance_ptr a pointer to an object of the same type, the call would be performed this way:
(chance.*m_redChances[0])();
(chance_ptr->*m_redChances[0])();
That is, by using the operators .* and ->*, respectively.
In your std::function example you can simply change
foo.getFunction(0);
to instead say
foo.getFunction(0)(foo);
This has to do with the same reason talked about in the other answers, a pointer to member-function is not in itself linked to an object. It needs a this to work on.
If you want to bind the std::function to a specific object you can use a
lambda to do that, like this.
#include <iostream>
#include <array>
#include <functional>
struct Foo {
std::array<std::function<void()>, 3> funArray; // Notice the change in signature to void()
Foo() {
funArray[0] = [&](){ fun1(); }; // Here & is catching this by reference and this lambda will always call fun1 on the current object.
funArray[1] = [&](){ fun2(); };
}
void fun1() {
std::cout << "fun1\n";
}
void fun2() {
std::cout << "fun2\n";
}
std::function<void()> getFunction(int i) {
return funArray[i];
}
};
int main() {
Foo foo;
foo.getFunction(0)(); // We get a function returned, so we need to call if by adding one more () at the end
auto storedFunction = foo.getFunction(1); // We can also store it
storedFunction(); // and call it later
}
A member function needs to be called on an object, to serve as the *this current object. You use the .* and ->* operators to call it with an object. E.g. (o.*mf)( args ).
Silly-fact noted by Andrei in his Modern C++ Programming book: o.*mf produces a callable entity that has no type.
In C++11 and later you can use std::function to effectively store such an object+function pointer pair, as a callable entity. Some other languages support it directly. E.g., it corresponds to a C# delegate.
Example.
#include <array>
#include <iostream>
using namespace std;
struct Foo
{
void blah() { cout << "Blah!" << endl; }
};
auto main()
-> int
{
array<void (Foo::*)(), 3> mf = {nullptr, nullptr, &Foo::blah};
Foo o;
Foo* o_ptr = &o;
(o_ptr->*mf[2])();
}

Keep a list of work to do in the future

Since function pointers need to know what arguments are supplied ahead of time I don't know how to do this.
Essentially I want a list of work. Each entry is a function to be called with specific arguments. I.e. I want to add foo(3, "abcd") to the work list, and then later bar(&h). That is, I don't know beforehand what types of functions will be added.
Later I will the iterate over this list and do the function calls specified.
Can this be implemented?
You're looking for std::function and either lambdas, or std::bind.
std::function is a wrapper for an arbitrary callable. You can store anything in it on which you can call operator() with the appropriate arguments.
One thing you can store in it are lambdas: you'd encapsulate the call and arguments into a non-argument lambda and call that.
Another thing you can store is the result of std::bind. std::bind is effectively a metafunction: it takes a function f and arguments as input, and returns a function object whose invocation results in invoking f on the arguments.
Here's how you could apply this to your case. The common setup:
std::vector<std::function<void()>> workList;
fillWorkList(workList);
for (auto& f : workList)
f();
And here are two possible implementations of fillWorkList. One with std::bind:
void fillWorkList(std::vector<std::function<void()>>& workList)
{
workList.push_back(std::bind(foo, 3, "abcd"));
workList.push_back(std::bind(bar, &h));
}
And one with lambdas:
void fillWorkList(std::vector<std::function<void()>>& workList)
{
workList.push_back([]() { foo(3, "abcd"); });
workList.push_back([]() { bar(&h); });
}
A std::function<void()> represents something that can be invoked, and returns nothing.
The clearest thing to store in it is a lambda.
std::function<void()> f = []{ foo(3, "abcd"); };
stores "call foo( 3, "abcd" ); in the std::function called f.
We can build a list of them -- a std::deque or std::vector -- and call them at a later time.
You can capture state in a lambda by putting what you want to capture within the []s:
std::function<void()> g = [h]{ bar(&h); };
This copies h into the lambda, then calls bar with a pointer to h. Sometimes you'll want h to be mutable:
std::function<void()> g = [h]()mutable{ bar(&h); };
You can also have lambdas that store references to variables. This is dangerous, as you are responsible for lifetime, and if you are storing the lambdas within std::functions then storing those in a container, lifetime may not be simple.
In C++14 you can even put expressions in the []s.
std::function<void()> behaves like a value. You invoke it with (), just like calling a function with signature void().
Using std::bind instead of lambdas is technically possible, but std::bind has many strange quirks and the code generated is usually less clear and errors are almost always unreadable. Don't do it.
You can also do this with a custom function object.
struct custom {
std::string s;
void operator()() const {
foo( 3, s );
}
};
Then std::function<void()> f = custom{ "abcd" }; is another way to say you'll invoke foo with 3, std::string("abcd") later when you f() on f.
Here is a solution, using a parameter pack, and perfect forwarding that allows for add(foo, 3, "abcd") to be used:
#include <functional>
#include <string>
#include <iostream>
#include <vector>
#include <utility>
void foo(int val, std::string text) { std::cout << val << '\t' << text << '\n'; }
void bar(int* ptr) { std::cout << *ptr << '\n'; }
class Worklist {
public:
template <typename ...Args>
void add(Args&&... args) {
worklist.push_back(std::bind(std::forward<Args>(args)...));
}
void do_all()
{
for(auto& i : worklist) {
i();
}
}
std::vector<std::function<void(void)>> worklist;
};
int main()
{
int h{9};
Worklist worklist;
worklist.add(foo, 3, "abcd");
worklist.add(bar,&h);
worklist.do_all();
}
It is possible to write a class that will accept lambdas as the tasks without using std::bind or std::function.
Here, a std::unique_ptr is used to store each of the lambdas:
#include <string>
#include <iostream>
#include <vector>
#include <memory>
#include <utility>
void foo(int val, std::string text) { std::cout << val << '\t' << text << '\n'; }
void bar(int* ptr) { std::cout << *ptr << '\n'; }
class Generic_Callable {
public:
~Generic_Callable() = default;
virtual void call() = 0;
};
template <typename T>
class MyCallable : public Generic_Callable {
public:
MyCallable(T &&t) : ptr{std::make_unique<T>(std::move(t))} {}
void call() override
{
(*ptr)();
}
std::unique_ptr<T> ptr;
};
class Worklist {
public:
template <typename T>
void add(T &&t)
{
worklist.push_back(std::make_unique<MyCallable<T>>(std::move(t)));
}
void do_all() {
for(auto& i : worklist)
i->call();
}
std::vector<std::unique_ptr<Generic_Callable>> worklist;
};
int main()
{
int h{9};
Worklist worklist;
worklist.add([]() {foo(3, "abcd"); });
worklist.add([&h]() {bar(&h); });
worklist.do_all();
}

Passing a class method as function argument

I am trying to send a method of a specific class instance as an argument to a function (foo), although I keep getting this error
invalid use of non-static member function...
(from the line foo(a->bar))
I'm not sure why do I get this error? Is there a possible work-around for it?
#include <iostream>
#include <functional>
void foo(std::function<void(void)> _func)
{
_func();
}
class A
{
public:
A()
{
x = 5;
}
void bar()
{
std::cout << x << std::endl;
}
private:
int x;
};
int main() {
A a;
foo(a->bar);
return 0;
}
You have two options:
Use std::bind: foo(std::bind(&A::bar, a)):
Use lambdas: foo([&a]() { a.bar(); });
Your method isn't compatible to std::function, even it looks like.
Every method has an implicit first argument, this.
So your signature looks like this
void bar(A* this) { /* ... */ }
This is not the case for static methods. These are like functions within the namespace of the class and
static void bar() { /* ... */ }
Will saturate std::function.
Still, using a lambda (c++11) is most likely the better way for ur example.

C++ function pointer

Is there a way in C++ to make an "untyed" function pointer ?
For example:
// pointer to global function
void foo( void (*fptr)() );
// pointer to member
void foo( void (Bar::*fptr)() );
Is there a way I can remove the class on which the member is ? So that I could do something like this:
void foo( void ("any type"::*fptr)(), "same type as for the pointer" &instance );
And then, in foo, I would like to store that pointer in a list, so that I can iterator over the list and call the function/member pointed to, regardless of what class it belongs to. Of course I'd need a list of instances on which to call the function.
Thx.
You can use a template.
template<typename T> void foo( void(T::*)(), T&) { ... }
However, people prefer to go for the function object approach. You can do this dynamically or statically.
void foo(std::function<void()> func) {
// std::bind is used to make this out of a member function
}
template<typename T> void foo(T t = T()) {
t(); // This is the best approach.
}
Edit: Some examples.
void foo(std::function<void()> func) {
std::cout << "In example one ";
func();
}
template<typename T> void foo(T t = T()) {
std::cout << "In example two ";
t();
}
class some_class {
public:
void func() { std::cout << "in ur function!\n"; }
};
int main(void)
{
some_class* ptr = NULL;
struct tempfunctor {
tempfunctor(some_class* newptr)
: ptr(newptr) {}
some_class* ptr;
void operator()() { return ptr->func(); }
};
foo(tempfunctor(ptr)); // Calls example two
foo(std::function<void()>(tempfunctor(ptr))); // Calls example one
foo(std::function<void()>(std::bind(&some_class::func, ptr)); // I'm not that familiar with bind, it looks something similar to this.
std::cin.get();
}
This is the idiom called the function object idiom, used heavily in STL and other high-quality libraries. The compile-time template is cleaner but the std::function can be bound at runtime.
Edit # OP: I didn't quite see your list requirement in there. A std::function<void()> is your best choice here.
The following seems to work fine with g++ and MSVC:
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
using namespace std;
void foo( boost::function<int()> f )
{
cout << "f() = " << f() << endl;
}
template< class Type >
void foo( int (Type::*f)() const, Type const& o )
{
foo( boost::bind( f, boost::ref( o ) ) );
}
int func1() { return 1; }
struct S { int func2() const { return 2; } };
int main()
{
foo( func1 );
foo( &S::func2, S() );
}
Disclaimer: I seldom use the Boost stuff and I just typed the above without bothering to check the docs, so possibly it could be expressed more cleanly.
Also note that C++0x standard library offers the same functionality.
Cheers & hth.,
No. The bound class is an intrinsic part of the member function pointer type.
You can, however, use a member function pointer to a common baseclass, or a template.
Can you use functors in your list?
http://en.wikipedia.org/wiki/Function_object
Have a look at Fast Delegates: http://www.codeproject.com/KB/cpp/FastDelegate.aspx
This is an easy drop-in library that allows you to delegate pretty much anything and at a very high speed.
template <typename T>
void foo( void (T::*fptr)(), T& instance)
{
// ...
}
I'm not going to play expert here, but I think this will work, if not I would like to know why.
You can't have a pointer like that, but you could have a collection of boost::any, and put heterogeneous pointers (or any kind of functors) into it.
You can't do that, and you shouldn't do that even if you could, because it is against the spirit of the language. Create a base class with "fptr" as a pure virtual member, and inherit all your classes from that class.