decltype的参数不正确

时间:2018-05-29 00:32:33

标签: c++ templates winapi decltype

两天前我问过创建使用Win32 API运行非静态类方法的线程,我几乎得到了一个解决方案,但有些让我感到困惑,所以我在发布答案之前先问这个问题我之前的问题。

我试图使用此代码来线程化具有未知返回类型的函数:

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);
}

当我尝试编译上面的代码时,我得到:

  

错误3556&#39; ordinaryfunc&#39;:错误的参数&#39; decltype&#39;

MSDN上描述了错误描述:

Compiler Error C3556

但是,在此之前我尝试了另一个代码,它运行得很好,但我的语法不是很好:

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
}

我知道此代码已足够,但我想使用Start(ltest)代替Start<int,ltest>()

注意:没有人说我应该在usualfunction中使用该函数作为参数,我将其用作模板参数,因为CreateThread()无法将函数作为一个函数传递参数。

3 个答案:

答案 0 :(得分:3)

模板参数必须在编译时知道。但是,您尝试使用普通函数参数func作为模板参数。

在第二个代码中,您将模板参数作为模板参数,这很好。

您的第一个代码出错的原因与此代码类似:

template<int X> void f() { }

int main(int argc, char **argv) { f<argc>(); }

虽然错误信息有点模糊。

从C ++ 17开始,您可以通过对第二个代码进行修改来获得所需的语法:

template <auto func>
int Start() {
    using R = decltype(func());
    // proceed as before...

并将其称为Start<ltest>();

在C ++ 17之前,您可以使用第二个代码的宏:

#define START(func) Start<decltype(func()), func>

答案 1 :(得分:0)

因为我使用的是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

答案 2 :(得分:0)

在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;
}

这个编好的