class CTest
{
public:
CTest(){}
~CTest(){}
public:
int Output(const char * szBuf)
{
std::cout << szBuf << std::endl;
return 0;
}
void AsyncMethod()
{
std::thread t(&CTest::Output, this, "hello, world");
t.join();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CTest obj;
obj.AsyncMethod();
}
In AsyncMethod(), there is a statement std::thread t(&CTest::Output, this, "hello, world");. What does & mean in this statement?
Firstly, this is not a lambda, right?
Secondly, here we need a pointer to a function. For a variable, & is used to acquire the address of the variable, but for a function, the name of the function itself is already the pointer to this function, right?
Thirdly, since AsyncMethod() and Output() are in the same class, why we need namespace CTest:: before Output?
So, why can't we write std::thread t(Output, this, "hello, world");?
Thank you for your help :)
Related
I was coding my function is properly returning a pointer to a reference.
I found that although the function was returning what it was suppose to do, however, std::cout was modifying the results.
Am I doing anything wrong here?
How to rectify this behaviour?
Please refer the following code snippet,
#include "stdafx.h"
#include <iostream>
using namespace std;
class MyClass
{
public:
MyClass(int x_):m_Index(x_){}
int m_Index;
};
void myfunction(int *¤tIndex, MyClass obj)
{
currentIndex = &obj.m_Index;
}
int _tmain(int argc, _TCHAR* argv[])
{
MyClass obj(5);
int *Index = NULL;
myfunction(Index, obj);
int curr_Index = *Index;
cout << "Index = " << curr_Index << std::endl; // This works fine.
cout << "Index = " << *Index << std::endl; // This modifies *Index
return 0;
}
void myfunction(int *¤tIndex, MyClass obj)
{
currentIndex = &obj.m_Index;
}
Invokes undefined behavior because obj is only valid for the life of the function call. You keep a pointer to it (or one of it's members) which you use AFTER it has gone out of scope.
You can solve either by pointing to something that doesn't go out of scope (see #songyuanyao's answer). In this case it isn't clear why you need pointers. myfunction could just return the index.
The obj parameter is passed by value, so a copy is made that will be destroyed when the function exits. currentIndex is being set to point to an invalid address, and dereferencing it is undefined behavior. It might work well, or it might not work, anything is possible.
One solution is to make obj be passed by reference instead of by value:
void myfunction(int *¤tIndex, MyClass& obj)
{
currentIndex = &obj.m_Index;
}
Here is my program below.
void fun1(void);
int main(int argc, char *argv[])
{
cout<<"In main"<<endl;
atexit(fun1); //atexit calls the function at the end of main
cout<<"Exit main"<<endl;
return 0;
}
void fun1(void)
{
cout<<"fun1 executed"<<endl;
}
The output is
In main
Exit main
fun1 executed
But I intend the output like this:
In main
fun1 executed
Exit main
I don't want to call "fun1" function directly or use any other functions which would call my function "fun1".
Is there any way I can acheive this this output? Any help is most welcome.
No. †
Only atexit and static object destruction happen "on their own", and both these things occur after returning from main.
And this makes sense, when you think about it: something that should occur during main should be written in main. If you need a function to be invoked at a given time, write it into your program. This is what you write the program for. main is for your program.
† Probably, with a "trick" or "hack" that'll get you fired from my team.
Here is a hack using a scope:
#include <iostream>
class call_on_destructed {
private:
void (*m_callee)();
public:
call_on_destructed(void (*callee)()): m_callee(callee) {}
~call_on_destructed() {
m_callee();
}
};
void fun() {
std::cout << "fun\n";
}
int main() {
{
call_on_destructed c(&fun);
std::cout << "In main" << std::endl;
}
std::cout<<"Exit main"<<std::endl;
}
Outputs:
In main
fun
Exit main
The scope end causes the class destructor to be invoked, which in turn calls the fun function, registered within the class.
Do you want something like:
void fun1(void)
{
std::cout << "fun1 executed" << std::endl;
}
void call(void f())
{
f();
}
int main(int argc, char *argv[])
{
std::cout << "In main" << std::endl;
call(fun1); //call calls the given function directly
std::cout << "Exit main" << std::endl;
return 0;
}
Clearly, if you want to have your function executed, something is going to call it! That is, calling your function without calling your function won't work. atexit() is also just calling your function: you register what's being called eventually.
From the sounds of it, your assignment asks to pass off a function object off and have that facility call your function. For example, you could use a function caller:
template <typename F>
void caller(F f) {
f();
}
int main() {
std::cout << "entering main\n";
caller(fun1);
std::cout << "exiting main()\n";
}
Clearly, caller() does call fun1 although without mentioning that name.
I want to do something like this code:
myType a;
a->foo();
void foo()
{
cout << a->bar();
}
void bar()
{
cout << a->bar2();
}
void bar2()
{
cout << a->bar3();
}
In another word, when a member function is called, can we use the original caller?
You want:
cout << this->bar();
Or, more simply
cout << bar();
This IBM C++ documentation explains it pretty well. Have a look.
What you're probably trying to do is something like this:
#include <iostream>
class myType {
void foo()
{
std::cout << bar();
}
void bar()
{
std::cout << bar2();
}
void bar2()
{
std::cout << bar3();
}
};
... and in e.g. main method:
int main(int argc, char** argv)
{
myType a;
a->foo();
}
Inside a class, you can refer to methods of the same class just by their name, and they will be called on the same object as the original method! If you want to highlight that you're referring to methods of the same object, use e.g. this->bar() instead of bar(); it is only necessary in cases where there are other names (e.g. method parameters) which would conceal the class members, but it can be used all the time.
I want the Windows thread pool (QueueUserWorkItem()) to call my class' member functions.
Unfortunately this cannot be done directly by passing a member function pointer as an argument to QueueUserWorkItem().
What makes it difficult is that more than one member function must be callable and they have different signatures (all return void though).
One probably need to add a few layers of abstraction to get this to work, but I'm not sure how to approach this. Any ideas?
This might help.
You can use tr1::function () and tr1::bind to "coalesce" various calls:
#include <iostream>
#include <tr1/functional>
using namespace std;
using namespace tr1;
class A
{
public:
void function(int i) { cout << "Called A::function with i=" << i << endl; }
};
void different_function(double c) {
cout << "Called different_function with c=" << c << endl;
}
int main(int argc, char* argv[])
{
function<void()> f = bind(different_function, 3.14165);
f();
A a;
f = bind(&A::function, a, 10);
f();
return 0;
}
The address of the function object can be passed as a single callable object (needing only one address).
Example:
In your class add:
char m_FuncToCall;
static DWORD __stdcall myclass::ThreadStartRoutine(LPVOID myclassref)
{
myclass* _val = (myclass*)myclassref;
switch(m_FuncToCall)
{
case 0:
_val->StartMyOperation();
break;
}
return 0;
}
Make a member for adding to queue then
void myclass::AddToQueue(char funcId)
{
m_FuncToCall=funcId;
QueueUserWorkItem(ThreadStartRoutine,this,WT_EXECUTEDEFAULT);
}
or create
typedef void (*MY_FUNC)(void);
typedef struct _ARGUMENT_TO_PASS
{
myclass* classref;
MY_FUNC func;
}ARGUMENT_TO_PASS;
and then
void myclass::AddToQueue(MY_FUNC func)
{
ARGUMENT_TO_PASS _arg;
_arg.func = func;
_arg.classref = this;
QueueUserWorkItem(ThreadStartRoutine,&_arg,WT_EXECUTEDEFAULT);
}
If you need further explanation feel free to ask :)
EDIT: You'll need to change the ThreadStartRoutine for the second example
and you can also change the struct to hold the passing argument
i want to do this simple piece of code work.
#include <iostream>
#include <windows.h>
void printSome (int i)
{
std::cout << i << std::endl;
}
void spawnThread (void (*threadName)(int i))
{
CreateThread
(
0, // default security attributes
0, // use default stack size
(LPTHREAD_START_ROUTINE)threadName, // thread function name
(LPVOID)i, // argument to thread function
0, // use default creation flags
0 // returns the thread identifier
);
}
int main ()
{
spawnThread(printSome(155));
}
i am on windows, using vs. Any help will be greatly appriciated.
CreateThread wants 2 arguments: pointer to the function to execute as a thread, and a DWORD argument that will be given to the thread. your spawnThread() function only has 1 argument (threadName); you think it has 2 args because of the "i", but that is really part of the definition of the "threadName" type. (you could just as well leave out the "i"; that is, you don't need to name the arguments to "threadName".)
anyway, given that you NEED 2 arguments, redefine spawnThread:
void spawnThread(void (*threadEntryPoint)(int), int argument)
{
CreateThread(0,0,
(LPTHREAD_START_ROUTINE)threadEntryPoint,
(LPVOID)argument,
0,0);
}
notice that i did not name the int argument to the threadEntryPoint; it is sufficient to tell the compiler that the function must have a single int argument.
and call it:
spawnThread(printSome, 155);
anyway, quick and dirty, this will do what you want.
hth.
reilly.
Personally, I wouldn't consider passing in a function pointer like you are trying to do as very C++ like. That's coding C in C++
Instead, I'd wrap that thing in a class. The big advantage there is you can just override the class to have however many members you want, rather than having to perform greazy casting tricks to get at your parameters every time.
The code's a little long-winded, so I pushed it to the end. But what it lets you do is something like this:
class print_some : public basic_thread {
private:
int i;
public:
print_some (int i) : i(i) {};
action_callback () {
std::cout << i << std::endl;
}
}
int main () {
print_some printer (155);
}
Here's some exerpted example code from one of our classes that does this:
class basic_thread :
{
public:
basic_thread();
protected:
unsigned long m_ThreadId;
virtual void action_callback () {};
// Internal routine used to bridge between OS callback format and
// action_callback. *Must* be static for the OS.
static unsigned long __stdcall self_calling_callback (void *parameter);
}
...and in the .cpp:
unsigned long __stdcall basic_thread::self_calling_callback (void *parameter) {
if (parameter) {
basic_thread * thread = reinterpret_cast<basic_thread *>(parameter);
thread->action_callback();
}
return 0; // The value returned only matters if someone starts calling GetExitCodeThread
// to retrieve it.
}
basic_thread::basic_thread () {
// Start thread.
m_Handle = CreateThread(NULL,
0,
self_calling_callback,
(PVOID)this,
0,
&m_ThreadId );
if( !IsHandleValid() )
throw StartException("CreateThread() failed", GetLastError());
}
You cannot pass parameter information in a function pointer; it must be passed separately. That is exactly why the CreateThread function provides a void* parameter that can point to whatever you want.
Additionally, you should use _beginthread instead of CreateThread for C++ applications.
Finally, your program is more than likely to terminate before the thread ever runs. Therefore, you must either enter an indefinite loop or use an API call to wait for the thread to finish.
The following is a working version using WaitForSingleObject to block until the thread completes.
#include <iostream>
#include <process.h>
#include <windows.h>
void
printSome(int i)
{
std::cout << i << std::endl;
}
HANDLE
spawnThread(void (*threadName)(int), int i)
{
return (HANDLE) _beginthread((void (*)(void*)) threadName, 0, (LPVOID) i);
}
int
main(int argc, char *argv[])
{
HANDLE threadHandle;
threadHandle = spawnThread(printSome, 155);
WaitForSingleObject(threadHandle, INFINITE);
return 0;
}
Here is a much more C++/object-oriented way of handling this same situation:
#include <iostream>
#include <process.h>
#include <windows.h>
class Thread {
static void proxy(void *arg) { (*(reinterpret_cast<Thread *> (arg)))(); }
HANDLE thread_;
public:
virtual ~Thread() {}
virtual void operator()() = 0;
void start() { thread_ = (HANDLE) _beginthread(Thread::proxy, 0, this);}
void waitForExit() { WaitForSingleObject(thread_, INFINITE); }
};
class Printer : public Thread {
int i_;
public:
Printer(int i) : i_(i) {}
void operator()() { std::cout << i_ << std::endl; }
};
int
main(int argc, char *argv[])
{
Printer p(155);
p.start();
p.waitForExit();
return 0;
}
As many people already mentioned here, you can't pass a function pointer and the argument it should be called with in one parameter.
Your line
spawnThread(printSome(155));
"should" (in DWIM world) mean "Invoke printSome on a separate thread with argument 155". However, it's not how C++ understands it. C++ sees "Pass the result of printSome invoked on 155 as a parameter to spawnThread". In other words, the sequence of steps is:
call prinotSome with 155 as argument. Store it in temporary memory.
call spawnThread with the contents of temporary memory as its argument.
In order to do what you really mean, you have to humor C++ and separate argument from function. How to do it is already explained in other answers. The short of it is:
callOnOtherThreadWithArgument(function, integer);
You can read how you do that here: http://www.newty.de/fpt/fpt.html
2.6 How to Pass a Function Pointer as an Argument ?
You can pass a function pointer as a
function's calling argument. You need
this for example if you want to pass a
pointer to a callback function. The
following code shows how to pass a
pointer to a function which returns an
int and takes a float and two char:
//------------------------------------------------------------------------------------
// 2.6 How to Pass a Function Pointer
// <pt2Func> is a pointer to a function which returns an int and takes a float and two char
void PassPtr(int (*pt2Func)(float, char, char))
{
int result = (*pt2Func)(12, 'a', 'b'); // call using function pointer
cout << result << endl;
}
// execute example code - 'DoIt' is a suitable function like defined above in 2.1-4
void Pass_A_Function_Pointer()
{
cout << endl << "Executing 'Pass_A_Function_Pointer'" << endl;
PassPtr(&DoIt);
}