Passing a class method as function argument - c++

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.

Related

Call a C-style function address with std::bind and std::function.target using a method from object

I have a C-style function, which stores another function as an argument. I also have an object, which stores a method that must be passed to the aforementioned function. I built an example, to simulate the desired situation:
#include <functional>
#include <iostream>
void foo(void(*f)(int)) {
f(2);
}
class TestClass {
public:
std::function<void(int)> f;
void foo(int i) {
std::cout << i << "\n";
}
};
int main() {
TestClass t;
t.f = std::bind(&TestClass::foo, &t, std::placeholders::_1);
foo( t.f.target<void(int)>() );
return 0;
}
What is expected is that it will be shown on screen "2". But I'm having trouble compiling the code, getting the following message on the compiler:
error: const_cast to 'void *(*)(int)', which is not a reference, pointer-to-object, or pointer-to-data-member
return const_cast<_Functor*>(__func);
As I understand the use of "target", it should return a pointer in the format void () (int), related to the desired function through std :: bind. Why didn't the compiler understand it that way, and if it is not possible to use "target" to apply what I want, what would be the alternatives? I don't necessarily need to use std :: function, but I do need the method to be non-static.
This is a dirty little hack but should work
void foo(void(*f)(int)) {
f(2);
}
class TestClass {
public:
void foo(int i) {
std::cout << i << "\n";
}
};
static TestClass* global_variable_hack = nullptr;
void hacky_function(int x) {
global_variable_hack->foo(x);
}
int main() {
TestClass t;
global_variable_hack = &t;
foo(hacky_function);
return 0;
}
//can also be done with a lambda without the global stuff
int main() {
static TestClass t;
auto func = [](int x) {
t->foo(x); //does not need to be captured as it is static
};
foo(func); //non-capturing lambas are implicitly convertible to free functions
}

How can I overload a member function from an instance of a class

I want to make a class where there is a function that is called automatically, to process information stored within this classes instance.
However each instance has different values and possibly a different way for that content to be handeled.
Therefore I need something simmilar to constructor overloading but in a member function. Where every instance can overload the default function or leave it up to the default to handle the input.
How can that be achieved?
Try to Call Functions in Constructor with if else condition
like:
class abc{
abc(){
if username == "member 1"
functioncall();
else
functioncall();
}
}
As far as I see you need some virtual construction emulation. There is a simple C/C++ way to do it.
// Example program
#include <iostream>
#include <string>
struct A;
typedef void (*cb)(A*);
struct A
{
int m_a;
static void foo(A* aref)
{
std::cout << "Print a: " << aref->m_a << "\n";
}
A(cb b=foo)
{
m_a = 100;
b(this);
}
};
int main()
{
A a;
}
It is not very clear, but still does the trick.
By creating a separate class for the variable behavior Callable describes the local data relating to the function, and by being a class, can be derived.
class Callable {
public:
int m_Value;
Callable(int value) : m_Value(value)
{
}
void operator()( int val1, double val2 /* whatever makes sense */ ) {
}
};
Using the function operator void operator()( ...... ) we create a way of making variables of type Callable to look like a function.
class Variable {
public:
Callable myFunction;
Variable(const Callable & howToCall, /* some more stuff */) :
myFunction(howToCall)
{ /* stuff */
}
void aFunction(int data, double value ) {
myFunction( data, value);
}
};
When calling aFunction the current value of myFunction is called.
Finally Variable can change which function it calls, by modifying the value of myFunction....
myFunction = Callable( /* new parameters */ );

Passing an inherited method to another method

I am trying to build a class that has a member function with a method as argument. The methods are defined in inherited classes. I build a minimal example:
#include <iostream>
struct base
{
base() {}
int number(int (*f)(int))
{
return f(1);
}
};
struct option1 : base
{
int timesTwo(int i){return 2*i;}
option1()
{
std::cout << number(timesTwo);
}
};
struct option2 : base
{
int timesThree(int i){return 3*i;}
int timesFour (int i){return 4*i;}
option2()
{
std::cout << number(timesThree);
}
};
int main()
{
option1 a; //I would expect this to print "2"
}
The current syntax in the function number is for a general function, but I cannot get it to work for a method of any inherited classes.
The problem here is that you're passing a pointer to a member function, which is completely different from a pointer to a non-member function (which is what your number function takes as an argument).
You could use std::function and std::bind:
int number(std::function<int(int)> f)
{
return f(1);
}
...
number(std::bind(&option1::timesTwo, this, _1));
You could also use templates, and extra arguments, like
template<typename T>
int number(T* object, int(T::*f)(int))
{
return (object->*f)(1);
}
...
number(this, &option1::timesTwo);
Or the simple (but not always correct, depending on situation and use case): Make the callback-function static:
static int timesTwo(int i){return 2*i;}
My recommendation is that you look over the solution using std::function, because then it's easy to call the number function with any type of callable object, like a lambda:
number([](int x){ return x * 2; });
The given error says :
error: reference to non-static member function must be called
You can just add static before your method members.
And I would suggest you to use std::function instead of pointer functions.
A working code :
#include <iostream>
#include <functional>
struct base
{
base() {}
int number(std::function<int(int)> f)
{
return f(1);
}
};
struct option1 : base
{
static int timesTwo(int i){return 2*i;}
option1()
{
std::cout << number(timesTwo);
}
};
struct option2 : base
{
static int timesThree(int i){return 3*i;}
static int timesFour (int i){return 4*i;}
option2()
{
std::cout << number(timesThree);
}
};
int main()
{
option1 a; // now it works
}

C++ Running a function pointer of class A from within class B as callback

I'm trying to run a method of one class from inside another class, I have a basic GUI that lets the user fill his name and password, and when it clicks the login button another takes over and handles the event, I would like to set a callback in case of a successful login, but I'm having problems sending the function pointer to my handler.
I made a raw example of what I'm trying to do.
#include <iostream>
using namespace std;
class LoginHandler {
public:
void loginAttempt(bool result)
{
if(result == true)
{
cout << "Login success! W00t!" << endl;
//Run my callback :)
callback();
} else {
cout << "Login failed." << endl;
}
}
void setCallback(void (*cb)())
{
callback = cb;
}
private:
void (*callback)();
};
class Foo {
public:
void run()
{
LoginHandler* loginHandler = new LoginHandler();
loginHandler->setCallback(&Foo::sayHello);
loginHandler->loginAttempt(false);
loginHandler->loginAttempt(true);
}
void sayHello()
{
cout << "You actually logged in! Isn't that amazing!?" << endl;
}
};
int main()
{
Foo foo;
foo.run();
return 0;
}
I'm getting the next error:
In member function 'void Foo::run()':
error: no matching function for call to 'LoginHandler::setCallback(void (Foo::*)())'
note: candidate is: void LoginHandler::setCallback(void (*)())
note: no known conversion for argument 1 from 'void (Foo::*)()' to 'void (*)()'
Thanks in advice.
Raw function pointers are mostly obsolete and should be used only for low-level performance-critical stuff. For the rest of us C++ has std::function which is infinitely better. It handles cases like yours with ease.
If you cannot use a it because you don't have a C++11 compiler, boost::function is a drop-in substitute.
You've specified that "setCallback" takes a function pointer, not a member-function pointer.
void setCallback(void (*cb)())
you are calling it - as the compiler complains - with a member-function pointer
loginHandler->setCallback(&Foo::sayHello);
In order to take a member function pointer, the setCallback definition is going to have to be able to determine what class to use, and the location where you call the callback is going to have to know what class so it can dereference the pointer.
Generally people solve this with a C-style callback handler, either
static FooSayHelloCallback(void* fooParam)
{
Foo* foo = static_cast<Foo*>(fooParam);
foo->sayHello();
}
or a functor object
struct LoginHandlerCallbackFunctor
{
void* m_this;
public:
FooSayHelloFunctor(void* this_) : m_this(this_) {}
virtual void operator()() = 0;
};
struct FooSayHelloFunctor : public LoginHandlerCallbackFunctor
{
public:
FooSayHelloFunctor(Foo* foo_) : LoginHandlerCallbackFunctor(foo_) {}
virtual void operator()() { ((Foo*)m_this)->sayHello(); }
};
Then
class LoginHandler {
...
LoginHandlerCallbackFunctor m_callback;
...
void setCallback(const LoginHandlerCallbackFunctor& functor)
{
m_callback = functor;
}
void doCallback()
{
m_callback(); // calls operator()
}
If you want to get really fancy you could maybe do that with templates.
Or, alternatively, you could use C++11 Lambdas and std::function.
class LoginHandler
{
typedef std::function<void(void)> GreetingCallback;
GreetingCallback m_callback;
...
void setCallback(const GreetingCallback& callback_)
{
m_callback = callback_;
}
void doCallback()
{
m_callback();
}
}
and in foo
LoginHandler loginHandler();
loginHandler.setCallback([=]() { sayHello(); });
loginHandler->loginAttempt(false);
loginHandler->loginAttempt(true);
sayHello should be a static function.
Because ordinary member functions have implicit parameter ¨this¨. So the full signature of sayHello is void sayHello(Foo* this);
Another way - use pointer to class member.
Also you can use functor structure instead of function.

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