I asked two days ago about creating threads to run non-static class methods with the Win32 API, and I almost got a solution but there is something confusing me, so I'm asking this question before posting the answer in my previous question.
I'm trying to use this code to thread a function with an unknown return type:
template <class R, R func() >
unsigned int usualfunc() {
func();
return 1;
}
template <class R>
int Start(R(*func)()) {
typedef decltype(&usualfunc<int, func>) D; // I get the error here , I can't get the address of the template function directly I need this
D p = &usualfunc<R, func>;
uintptr_t add = (uintptr_t)p;
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)add, 0, 0, 0);
func();
return 1;
}
int main() {
Start(ltest);
}
When I try to compile the above code, I get :
error 3556 'usualfunc': incorrect argument to 'decltype'
The error description is described on MSDN:
However, I tried another code before this, and it works just fine, but I wasn't very good with the syntax:
template <class R, R func() >
unsigned int usualfunc() {
func();
return 1;
}
template <class R,R func()>
int Start() {
typedef decltype(&usualfunc<int, func>) D; // works well
D p = &usualfunc<R, func>;
uintptr_t add = (uintptr_t)p;
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)add, 0, 0, 0);
func();
return 1;
}
int main() {
Start<int,ltest>(); // works
}
I know this code is enough, but I'd like to use Start(ltest)
instead of Start<int,ltest>()
.
Note: no one say that I should use the function as parameter in usualfunction
, I'm using it as a template parameter because CreateThread()
can't pass a function as a parameter.
Template parameters must be known at compile-time. However you attempt to use the normal function parameter func
as a template argument.
In the second code you give a template parameter as the template argument, which is fine.
Your first code is wrong for a similar reason as this code:
template<int X> void f() { }
int main(int argc, char **argv) { f<argc>(); }
although the error message is a bit more obscure.
Since C++17 you can get the syntax you want by making this modification to your second code:
template <auto func>
int Start() {
using R = decltype(func());
// proceed as before...
and call it as Start<ltest>();
.
Prior to C++17 you could use a macro with your second code:
#define START(func) Start<decltype(func()), func>