What is the correct way of passing a member function to thread
class foo{
public:
int sum(int a ,int b)
{
std::cout<<a+b;
}
};
i need to pass this function to a thread in my main function.I have seen an example
#include <thread>
#include <iostream>
class SayHello
{
public:
void greeting(std::string const& message) const
{
std::cout<<message<<std::endl;
}
};
int main()
{
SayHello x;
std::thread t(&SayHello::greeting,&x,"goodbye");
t.join();
}
why do we need to pass the reference to the object in this case?
why do we need to pass the reference to the object in this case?
A member function, apart from the "normal" arguments, also takes a pointer to the object (this). This one is implicitly provided when you call with the normal syntax:
x.apply_greeting("goodbye"); //secretly calls apply_greeting(&x,"goodbye"). (not valid code!)
So when you have a pointer to a member function which you have when you write &SayHello::greeting, you need to provide the pointer to the object as well. Otherwise - how would it know about its member variables?
Pointer to member functions are messy, you can circumvent by using a lambda:
std::thread t([&x](){ x.greeting("goodbye!"); } );
I know it's not a perfect answer to the question. But in my experience of C++03, manage member functions is a hard work, especally when the code is shared with beginners in C++. My habit is the following:
class SayHello
{
public:
void greeting(std::string const& message) const
{
std::cout << message << std::endl;
}
};
void apply_greeting(SayHello const* say_hello, std::string const* message)
{
say_hello->greeting(*message);
}
int main()
{
SayHello x;
const std::string message = "goodbye";
std::thread t(apply_greeting, &x, &message); // I'm not sure for this line, my habit is C++03 with boost::thread and boost::bind
t.join();
return 0;
}
Related
The following is a timer.
template <typename Duration, typename Function>
void timer(Duration const & d, Function const & f)
{
std::thread([d,f](){
std::this_thread::sleep_for(d);
f();//error here
}).detach();
}
Sample myclass definition is
class myclass {
public:
void my_functions() const {
std::cout << "my_functions called";
}
};
And I call it like this:
timer(std::chrono::milliseconds(10), &myclass::my_functions());
When I try to call it on a member function I get error C2064: term does not evaluate to a function taking 0 arguments
To pass a non-static member function to another function you need to utilize std::function and std::bind from functional header, as well as instantiate the object
myclass mc;
timer(std::chrono::milliseconds(1), std::bind(&myclass::my_functions, mc));
However, your code might not work as expected, because to see the message you must wait for the thread to make a call. Here's a simple example of a working one
#include <thread>
#include <iostream>
#include <functional>
#include <chrono>
template <typename Duration, typename Function>
void timer(Duration const & d, Function const & f)
{
std::thread([d, f](){
std::this_thread::sleep_for(d);
f();//error here
}).detach();
}
class myclass{
public:
void my_functions() const {
std::cout << "aaa";
}
};
int main(){
myclass mc;
timer(std::chrono::milliseconds(1), std::bind(&myclass::my_functions, mc));
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
}
The proper way would be of course to wait for thread completion.
Also, if the sole purpose of your member function is to output a message, you can make it static and do without binding.
You cannot call non-static methods/functions without an object instance (even if the object is not really needed inside the method/function).
To achieve a method call without the need for an object, declare that method static (can still be inside the class, but add static before its name).
If you are okay to charge argument list of your timer() function then this will also works.
#include <iostream>
#include <chrono>
#include <thread>
template <typename Duration, typename Function, typename Class>
void timer(Duration const & d, Function const & f,Class const& o)
{
std::thread([d,f,o](){
std::this_thread::sleep_for(d);
f(o);//error here
}).detach();
}
class Foo{
public:
Foo() {}
void func() const {
std::cout<<__func__<<":"<<__LINE__<<std::endl;};
}
int main(){
std::function<void(const Foo&)> foo_func = &Foo::func;
const Foo foo;
timer(std::chrono::seconds(2),foo_func,foo);
std::this_thread::sleep_for(std::chrono::seconds(5));
return 0;
}
The issue here is a non static member function is not the same as a regular or static function. It has a hidden parameter that it takes and that is pointer to the object the function is being called on.
You have a couple ways to fix this. First you can make it static and then it treats it just like a normal function whose name is scopeed to the class. If you cannot do that then you can use std::bind to create function like object that you can call the function operator on. It would be used like
timer(std::chrono::milliseconds(10), std::bind(&class_name::my_functions(), &class_instance));
Lastly you could use a lambda to wrap the call just like bind does. For that the syntax would be
timer(std::chrono::milliseconds(10), [&class_instance](){
return class_instance.my_functions();
});
Alright, I think the title is sufficiently descriptive (yet confusing, sorry).
I'm reading this library: Timer1.
In the header file there is a public member pointer to a function as follows:
class TimerOne
{
public:
void (*isrCallback)(); // C-style ptr to `void(void)` function
};
There exists an instantiated object of the TimerOne class, called "Timer1".
Timer1 calls the function as follows:
Timer1.isrCallback();
How is this correct? I am familiar with calling functions via function pointers by using the dereference operator.
Ex:
(*myFunc)();
So I would have expected the above call via the object to be something more like:
(*Timer1.isrCallback)();
So, what are the acceptable options for calling functions via function pointers, as both stand-alone function pointers and members of an object?
See also:
[very useful!] Typedef function pointer?
Summary of the answer:
These are all valid and fine ways to call a function pointer:
myFuncPtr();
(*myFuncPtr)();
(**myFuncPtr)();
(***myFuncPtr)();
// etc.
(**********************************f)(); // also valid
Things you can do with a function pointer.
1: The first is calling the function via explicit dereference:
int myfunc(int n)
{
}
int (*myfptr)(int) = myfunc;
(*myfptr)(nValue); // call function myfunc(nValue) through myfptr.
2: The second way is via implicit dereference:
int myfunc(int n)
{
}
int (*myfptr)(int) = myfunc;
myfptr(nValue); // call function myfunc(nValue) through myfptr.
As you can see, the implicit dereference method looks just like a normal function call -- which is what you’d expect, since function are simply implicitly convertible to function pointers!!
In your code:
void foo()
{
cout << "hi" << endl;
}
class TimerOne
{
public:
void(*isrCallback)();
};
int main()
{
TimerOne Timer1;
Timer1.isrCallback = &foo; //Assigning the address
//Timer1.isrCallback = foo; //We could use this statement as well, it simply proves function are simply implicitly convertible to function pointers. Just like arrays decay to pointer.
Timer1.isrCallback(); //Implicit dereference
(*Timer1.isrCallback)(); //Explicit dereference
return 0;
}
You don't have to dereference a function pointer to call it. According to the standard ([expr.call]/1),
The postfix expression shall have
function type or pointer to function type.
So (*myFunc)() is valid, and so is myFunc(). In fact, (**myFunc)() is valid too, and you can dereference as many times as you want (can you figure out why?)
You asked:
Timer1 calls the function as follows:
Timer1.isrCallback();
How is this correct?
The type of Timer1.isrCallback is void (*)(). It is a pointer to a function. That's why you can use that syntax.
It is similar to using:
void foo()
{
}
void test_foo()
{
void (*fptr)() = foo;
fptr();
}
You can also use:
void test_foo()
{
void (*fptr)() = foo;
(*fptr)();
}
but the first form is equally valid.
Update, in response to comment by OP
Given the posted definition of the class you would use:
(*Timer1.isrCallback)();
To use
(Timer1.*isrCallback)();
isrCallback has to be defined as a non-member variable of whose type is a pointer to a member variable of TimerOne.
void (TimerOne::*isrCallback)();
Example:
#include <iostream>
class TimerOne
{
public:
void foo()
{
std::cout << "In TimerOne::foo();\n";
}
};
int main()
{
TimerOne Timer1;
void (TimerOne::*isrCallback)() = &TimerOne::foo;
(Timer1.*isrCallback)();
}
Output:
In TimerOne::foo();
(Test this code)
If you want to define isrCallbak as a member variable of TimerOne, you'll need to use:
#include <iostream>
class TimerOne
{
public:
void (TimerOne::*isrCallback)();
void foo()
{
std::cout << "In TimerOne::foo();\n";
}
};
int main()
{
TimerOne Timer1;
Timer1.isrCallback = &TimerOne::foo;
// A little complicated syntax.
(Timer1.*(Timer1.isrCallback))();
}
Output:
In TimerOne::foo();
(Test this code)
My title is my main question.
The code below shows what i want to do, but it causes an error.
class B
{
public:
void DoSomething(void (*func)())
{
func();
}
};
class A
{
public:
int x;
void Start(B* b)
{
auto func = [this]()->void
{
this->x++;
};
b->DoSomething(func);
}
};
If I remove the "this" keyword, then the program works, but then I cant reference the x variable.
So how can I achieve this?
Change
void DoSomething( void (*func)() )
to
void DoSomething( std::function<void()> func )
Your current parameter type void (*func)() is a function pointer, which is a type of callable (something that can be called like a function) that doesn't hold state. That is why your variable this can't be passed into the function.
Only lambdas that capture nothing can be converted to a stateless function pointer.
std::function however can represent (almost) anything callable. It could be a raw function, or an instance of a class that implements operator(), or it could be your lambda holding state.
An alternative is to simply use templates to avoid the potential overhead associated with large lambdas that need to be packaged by std::function.
#include <functional>
using namespace std;
template<typename Callable>
void DoSomething(Callable c) { c(); } // calls the lambda with no args
int main()
{
DoSomething([]{ printf("Hello\n"); });
DoSomething([msg = "World"] { printf("%s\n", msg); });
}
Live Code: http://goo.gl/LMvm3a
I'm new to C++11 thread , when reading a tutorial , I see a piece of code like this.
#include <thread>
#include <iostream>
using namespace std;
class background_task
{
public:
void operator()() const
{
cout<<"This is a new thread";
}
};
int main()
{
background_task f;
std::thread my_thread(f);
my_thread.join();
}
The output will be "This is new thread", but i don' really understand what does the function "operator()() const" mean?. In this case, it acts really the same with the constructor, is it right?.
And how can C++ have a syntax like that? I have search about related topic by using the search engine but no found no result.
Thanks in advanced.
void operator()() means an instance of the class with that operator can be called with function call syntax, with no return value, and without any parameters. For example:
background_task b;
b(); // prints "This is a new thread"
The operator() part indicates it is a call operator, the second set of empty parentheses () indicate the operator has no parameters. Here is an example with two parameters and a return value:
struct add
{
int operator()(int a, int b) const { return a + b; }
};
add a;
int c = a(1, 2); // c initialized to 1+2
Note that this syntax pre-dates C++11. You can create callable types (also referred to as functors) in C++03. The connection with C++11 is that the std::thread constructor expects something that can be called without arguments . This could be a plain function
void foo() {}
a static member function
struct foo {
static void bar() {}
};
an instance of a type such as background_task, a suitable lambda expression, a suitable invocation of std::bind, in short, anything that can be called without arguments.
It's just operator overloading and has nothing to do with C++11 or multi-threading. An overloaded operator is just a normal function with a funny name (this may be a bit oversimplified, but it's a good rule of thumb for beginners).
Your class has a function named (). That's all. Technically, you could as well have named the function foo or f or TwoParentheses.
Consider a simpler example:
#include <iostream>
class Example
{
public:
void operator()() { std::cout << "()"; }
void foo() { std::cout << "foo"; }
void TwoParentheses() { std::cout << "TwoParentheses"; }
};
int main()
{
Example e;
e.operator()();
e.foo();
e.TwoParentheses();
}
Now calling an overloaded operator like in this example in main, spelling out the entire .operator() part, is pretty pointless, because an overloaded operator's purpose is to make the calling code simpler. You would instead invoke your function like this:
int main()
{
Example e;
e();
}
As you can see, e(); now looks exactly as if you called a function.
This is why operator() is a special name, after all. In a template, you can handle objects with operator() and function pointers with the same syntax.
Consider this:
#include <iostream>
class Example
{
public:
void operator()() { std::cout << "Example.operator()\n"; }
};
void function() { std::cout << "Function\n"; }
template <class Operation>
void t(Operation o)
{
o(); // operator() or "real" function
}
int main()
{
Example object;
t(object);
t(function);
}
This is the reason why operator() is an important function in C++ generic programming, and is often required.
It has nothing to do with C++11, it's the function call overload operator. That means if you have a class like yours, you can create an instance of it and use as a function:
int main()
{
background_task bt;
bt();
}
The above main function should give the same result as your simple thread example.
it is operator over loading. the user provide an additional use to () operator. Example for static polymorphism. it is fearture of Object orieted program
I've applied solutions based on some search made, but the problem still there. Thank you so much for the help.
error: must use '.*' or '->*' to call pointer-to-member function ...
source code:
#include <stdio.h>
class A
{
public:
struct data;
typedef int (A::*func_t)(data *);
typedef struct data
{
int i;
func_t func;
}
data;
data d;
void process()
{
d.func(&d);
}
A()
{
d.i = 999;
d.func = &A::print;
}
int print(data *d)
{
printf("%d\n", d->i);
return 0;
}
};
int main()
{
A *a = new A;
a->process();
return 0;
}
d.func(&d);
is not enough. func is a member-function-pointer which is pointing to a non-static member of A. So it can be invoked on an object of A. So you need to write this:
(this->*(d.func))(&d);
That would work as long as you write this inside A.
If you want to execute func from outside, say in main(), then the syntax is this:
A a;
(a.*(a.d.func))(&a.d);
That is an ugly syntax.
Your process function attempts to call d.func but it is a pointer to member function. A pointer to member function must be called on some object. Presumably you want the instance of A to be this, in which case your process function should look like:
void process()
{
(this->*(d.func))(&d);
}
Note the use of the ->* operator to call a member function when you have a pointer to it.
Other answers have already said you need to say (this->*d.func)(&d) to call a pointer-to-member function (because you need to provide the object that it's a member of)
Another option is to make the function a static function, which doesn't need special syntax to call. To do that, change the typedef like so:
typedef int (*func_t)(data *);
Then make the print function static:
static int print(data *d)
{
...
}
Now you can just call d.func(&d)
Unfortunately what you are trying to do will not be possible, the reason being that print is not a static member function. This means it expects an implicit first argument that is the this pointer.
I suggest you try using the std::function and std::bind function, something like this:
class A
{
struct data
{
std::function<void(const data&)> func;
int i;
};
data d;
public:
A()
{
d.func = std::bind(&A::print, *this);
d.i = 999;
}
void process()
{
d.func(d);
}
void print(const data& my_data)
{
std::cout << my_data.i << '\n';
}
};
Of course, since the print function now have a proper this pointer, you no longer need to pass the data structure to it:
class A
{
struct data
{
std::function<void()> func;
int i;
};
data d;
public:
A()
{
d.func = std::bind(&A::print, *this);
d.i = 999;
}
void process()
{
d.func();
}
void print()
{
std::cout << d.i << '\n';
}
};
Calling pointer the members require the class it is a member of to be the this param.
Try:
A a;
a.*(d.func)(&d);