C++ decltype的参数不正确
两天前我问过关于创建线程来运行带有Win32 API的非静态类方法的问题,我几乎得到了一个解决方案,但有一些问题让我困惑,所以我在发布前一个问题的答案之前先问这个问题 我正在尝试使用此代码对具有未知返回类型的函数执行线程:C++ decltype的参数不正确,c++,templates,winapi,decltype,C++,Templates,Winapi,Decltype,两天前我问过关于创建线程来运行带有Win32 API的非静态类方法的问题,我几乎得到了一个解决方案,但有一些问题让我困惑,所以我在发布前一个问题的答案之前先问这个问题 我正在尝试使用此代码对具有未知返回类型的函数执行线程: template <class R, R func() > unsigned int usualfunc() { func(); return 1; } template <class R> int Start(R(*func)()) {
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);
}
模板
unsigned int usualfunc(){
func();
返回1;
}
模板
int开始(R(*func)(){
typedef decltype(&usualfunc)D;//我在这里得到了错误,我不能直接得到模板函数的地址,我需要这个
dp=&usualfunc;
uintpttr_t add=(uintpttr_t)p;
CreateThread(0,0,(LPTHREAD\u START\u例程)add,0,0,0);
func();
返回1;
}
int main(){
启动(ltest);
}
当我尝试编译上述代码时,我得到:
错误3556“usualfunc”:对“decltype”的参数不正确
MSDN中描述了错误说明:
然而,在此之前我尝试了另一个代码,它工作得很好,但我对语法不是很好:
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
}
模板
unsigned int usualfunc(){
func();
返回1;
}
模板
int Start(){
typedef decltype(&usualfunc)D;//工作正常
dp=&usualfunc;
uintpttr_t add=(uintpttr_t)p;
CreateThread(0,0,(LPTHREAD\u START\u例程)add,0,0,0);
func();
返回1;
}
int main(){
Start();//有效
}
我知道这个代码已经足够了,但是我想使用Start(ltest)
而不是Start()
注意:没有人说我应该在
usualfunction
中将函数用作参数,我将它用作模板参数,因为CreateThread()
无法将函数作为参数传递。模板参数必须在编译时已知。但是,您尝试使用普通函数参数func
作为模板参数
在第二段代码中,您提供了一个模板参数作为模板参数,这很好
您的第一个代码错误,原因与此代码类似:
template<int X> void f() { }
int main(int argc, char **argv) { f<argc>(); }
template void f(){}
intmain(intargc,char**argv){f();}
尽管错误信息有点模糊
从C++17开始,您可以通过对第二个代码进行以下修改来获得所需的语法:
template <auto func>
int Start() {
using R = decltype(func());
// proceed as before...
#define START(func) Start<decltype(func()), func>
模板
int Start(){
使用R=decltype(func());
//照旧进行。。。
并将其命名为Start();
在C++17之前,您可以在第二个代码中使用宏:
template <auto func>
int Start() {
using R = decltype(func());
// proceed as before...
#define START(func) Start<decltype(func()), func>
#定义开始(func)开始
因为我使用的是visual studio 2015,无法使用自动模板,所以我使用了m.m所说的宏,并以此结束
Thread t;
t.SetFunc(ltest);
t.SetMember(testt, testf, tt); // class type , member function , pointer to class , it's like this : testt::testf , I can use this outside of class
t.SetMember(testt, testf, this); // from a member of the class , this is a pointer to the class , as I use this inside the member I can also thread private members here
在visual studio 2015中使用clang cl 5或6:
template <auto func>
int Start() {
using R = decltype(func());
typedef decltype(&usualfunc<R, func>) D;
D p = &usualfunc<R, func>;
uintptr_t add = (uintptr_t)p;
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)add, 0, 0, 0);
return 1;
}
模板
int Start(){
使用R=decltype(func());
typedef decltype(&usualfunc)D;
dp=&usualfunc;
uintpttr_t add=(uintpttr_t)p;
CreateThread(0,0,(LPTHREAD\u START\u例程)add,0,0,0);
返回1;
}
这个编译得很好“但是语法不是很好”,在什么前提下?请编辑你的代码成为一个MCVEsorry我的英语不是很好,我的意思是写
Start();
比Start(ltest)
更复杂,特别是当我与类成员一起使用它时,我当前的代码是这样工作的:class testt{unsigned int testf(){….};testt*tt=new testt;Thread t;t.Set(tt)
我尝试过,但我正在使用的vs 2015不支持自动模板,并且在将其用作类成员时,宏不能作为选项。没有任何方法可以将函数参数用作类型吗?您仍然可以使用宏或只写出decltypeI我想将函数用作类的构造函数,但我不能,因为我无法不要在构造函数中使用模板参数,所以我使用它作为成员,它可以工作,但正如我所说的,问题只存在于函数的使用中,真的没什么好担心的。clang 6和5支持自动?如果是,我有clang cl 5,它应该可以做到it@dev65使用标志-std=c++17