Calling function from std::array of function pointers - c++

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])();
}

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.

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.

How do I compare a std::function's target with a member function's address?

I am trying to figure out how to compare a function object's target (which is a member function) with the actual member function.
Of course, they should match.
But I don't get them to match, and I am lost with the syntax for declaring a member function as the type for the function object.
Here is some code:
#include <cstdlib>
#include <iostream>
#include <functional>
using namespace std;
class Object {
public:
void method () {}
};
int main(int argc, char** argv) {
Object* obj = new Object();
function<?????> wrapper = bind(&Object::method, obj);
if (wrapper.target<?????>() == &Object::method) {
cout << "match" << "\n";
} else {
cout << "no match" << "\n";
}
delete(obj);
return 0;
}
I tried to put different things instead of the ?????, but without any success.
So, what do I write instead of the questions marks, or are there other problems with this code?
function<?????> wrapper = bind(&Object::method, obj);
The bind expression returns a callable object that requires no arguments and returns void, so the logical call signature is void() and so you want std::function<void()>.
if (wrapper.target<?????>() == &Object::method) {
This won't work, because the function doesn't hold the pointer-to-member-function, it holds the result of the bind expression, which wraps the pointer-to-member-function.
The type returned by the bind expression (and therefore the type of the function's target) is some internal implementation detail such as _Binder<void, _Mem_fn<Object, void()>, Object*>, which you can't refer to directly.
You could do:
auto b = bind(&Object::method, obj);
function<void()> wrapper = b;
if (wrapper.target<decltype(b)>() != nullptr) {
But this doesn't tell you anything useful.

Setting a callback function which is non static member function of a class

typedef void (*CALLBACK)();
class Filter
{
public:
void callback()
{
cout << "callback" << endl;
}
};
void SetCallback(CALLBACK pCallBack )
{
pCallBack();
}
int main()
{
Filter f;
SetCallback(f.callback);
}
In main, SetCallback(f.callback); statement is giving error. Can anyone help me to fix the issue
The problem is that a member function isn't a plain function without parameters, because it always has the implicit this parameter.
If you encounter a legacy C interface that requires a plain callback function without a user context parameter (a void* that the function just passes on to the callback) you have a problem.
If you do have the user context, it's easy. Pass the object pointer as the context, and use a wrapper function as the actual callback:
typedef void (*CALLBACK)(void*);
class Filter
{
public:
static void CallbackWrapper(void* context) {
static_cast<Filter*>(context)->callback();
}
private:
void callback();
};
int main() {
Filter f;
SetCallback(&Filter::CallbackWrapper, &f);
}
If you don't have the context, here are some options:
Store the object in a global variable and access it from a wrapper. This has the obvious downsides of using a global variable, and not allowing more than one callback this way. For long-running callbacks this is really bad.
A small improvement to the above is to use a thread-local global variable. This is interesting for tightly scoped callbacks, e.g. you call a function that will immediately use your callback multiple times and then return. Think qsort(). At least this way, you don't get the thread safety issues. Still not an option for long-running callbacks.
Finally, the option that works on most platforms but is a lot of work, you can generate a stub function at runtime which embeds the object pointer. This basically means allocating a piece of memory, disabling execution protection on that memory if the platform uses this, and put machine code there that loads the object pointer and calls the function on it.
The final option still has lots of downsides: it's extremely platform-specific and may not even work at all on some (you can't disable execution protection in iOS, AFAIK), it's CPU-specific (since you need to generate the right code for each), and there's the issue of managing the memory for the stub. On the other hand, sometimes it's the only thing that works. Delphi does this kind of stuff for its window and hook procedures sometimes, and the ATL does so too.
Here is a method I've used to implement a callback to a pointer to member function.
It might require C++11.
#include <iostream>
#include <string>
#include <functional>
using namespace std;
struct MessageSource
{
function<void(const string& msg)> _callback;
template<typename A, typename B>
void connect(A func_ptr, B obj_ptr)
{
_callback = bind(func_ptr, obj_ptr, placeholders::_1);
}
void send_msg(const string& msg)
{
if (_callback)
_callback(msg);
}
void disconnect()
{
_callback = nullptr;
}
};
struct Printer
{
void print(const string& msg) { std::cout << msg << std::endl; };
};
int main()
{
{
Printer p;
MessageSource s;
s.connect(&Printer::print, &p);
s.send_msg("test");
s.disconnect();
s.send_msg("test again");
}
system("pause");
return 0;
}
A simplier example about callback for 'non-static method' :
#include <iostream>
#include <string>
#include <functional>
using namespace std::placeholders;
class Test
{
public:
void SetValue(int i) { v = i;}
int v;
};
int main()
{
Test a { 123 };
std::cout << a.v << std::endl; // print 123
auto _callback = std::bind(&Test::SetValue, &a, _1); // create the callback
_callback(55); // call the callback
std::cout << a.v << std::endl; // print 55
return 0;
}
output :
123
55
You should think about what a callback really is and how a member function is called.
When you give a callback function, you just give the address of a function that will later be called with parameters on which you normally have little control.
When a member function is called, its first parameter is the this pointer, that is a reference to the object on which the method is called.
That's the reason why it is not possible to use a member method as a callback. You can only use true functions or static member functions that do not need the special (implicit for programmer but real in a compiler point of view) parameter this.

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

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