Is it possible to pass a template to a thread using the WinAPI?
I'm trying to call _beginthreadex and pointing it to a function which takes a template but it gives me the error
'_beginthreadex' : cannot convert parameter 3 from 'unsigned int (__stdcall *)(void *)' to 'unsigned int (__stdcall *)(void *)'
Which to me makes no sense, but I am guessing it throws that error because _beginthreadex is not made to handle functions that accept templates.
Since what I am trying most likely won't ever work... Is there a way to make a global template? At the moment I have a class which contains a member function which accepts a class type as a template. I want to pass this template onto a newly created thread but I can't get around the problem of _beginthreadex. Is there anyway to directly pass a template type/value from one function to another?
It was my understanding that templates are kinda inherited, when Create calls ThreadFunction the template is passed on to it, which is then passed onto Run.
EDIT: Well it works if I put the entire thread class under a single template<class T> and remove the others but then you have to create a new Thread object each time you want to make a new thread. I had hoped there was a way to create a single Thread object which could manage any child threads and create new ones.
1) Your names aren't ideal. A "Thread" logically sounds like it'd be a singular thread, but your thread class here is actually keeping track of a group of threads. Something like "ThreadManager" or the like would make more sense.
2) Rather than use templates here ... polymorphism would be a better approach. IE, have your individual thread classes (such as 'Test') derive from a common 'ThreadBase' base class.
3) This is bad:
1 2 3 4 5
Test()
{
cout << "\nWOAH\n";
deletethis; // RED FLAG!
}
Suicide in a ctor is risky business if you're not careful. I gather this is just a temporary measure and you won't actually have your program work this way when it's done, but this threw up all sorts of red flags in my brain.
4) Another design idea might be to make this class a singleton and not make the user generate an instance of it. ThreadBase (and derived) classes could add themselves to the singleton group in their ctor or something. Just be sure to be carefule and watch out for the static order initialization fiasco.
5) This:
1 2 3 4
namespace ThreadThing
{
Thread Thread;
};
Are you TRYING to cause confusion / name conflicts?
you have to create a new Thread object each time you want to make a new thread
That doesn't make sense to you?
I had hoped there was a way to create a single Thread object which could manage any child threads and create new ones.
What you want is a ThreadManager class, although how it's going to manage Thread<T> with different values of T is beyond me.
What you should do, I think, is change the call to _beginthreadex():
ThreadID = (HANDLE)_beginthreadex(NULL,0,ThreadFunction<T>, this, 0, NULL);
And to Run():
return static_cast<Thread*>(lparam)->Run<T>();
How were you expecting the templates to figure out the values of their parameters?
I had been worried more about getting the program to work first and then I would change the names to something more informative.
My idea was to make a single class that could create Threads which would run one or more classes. Each time a new thread is created a new instance of a class would be created inside that thread and the original Thread class, lets call it ThreadManager from now on, would store the handle and any of information about that thread in a vector/map. That way ThreadManager would contain all the information about any child threads created by the program and choose to terminate or suspend them as needed, I had planned on each class having a constructor that would guide the thread, with the class suiciding once it's task was finished, sending a "done" message to the ThreadManager and closing the thread automaticly.
Telling the ThreadManager which class to create in which thread is where the template was supposed to come in, Run() would create a new instance of the class T inside the thread, which would trigger the classes constructor.
It is my first time using templates though so I was unsure as to how they worked... I'll make the changes you suggested tomorrow when I get the chance and see if they fixed the problem.