我正在研究线程池,为了避免使用过长的限定符名称,我想使用 typedef
声明。
但事实并不像看起来那么简单:
typedef unsigned ( __stdcall *start_address )( void * ) task;
当我尝试那种方式时,我得到了:
error C3646: 'task' : unknown override specifier
错误,在使用这个声明进行一段时间后,我卡住了,找不到任何合理的解决方案来声明这种类型的 typedef
。
我正在研究线程池,为了避免使用过长的限定符名称,我想使用 typedef
声明。
但事实并不像看起来那么简单:
typedef unsigned ( __stdcall *start_address )( void * ) task;
error C3646: 'task' : unknown override specifier
错误,在使用这个声明进行一段时间后,我卡住了,找不到任何合理的解决方案来声明这种类型的 typedef
。
当创建一个函数指针的typedef
别名时,别名就在函数名称位置,因此使用:
typedef unsigned (__stdcall *task )(void *);
task
现在是一个类型别名, 表示指向一个函数的指针, 该函数接受一个 void
指针并返回一个 unsigned
值。
由于hmjd的答案已被删除...
C++11开发了全新的别名语法,使这些操作更加容易:
using task = unsigned (__stdcall*)(void*);
等价于 typedef unsigned (__stdcall* task)(void*);
(注意别名在函数签名中间的位置...)。
它也可以用于模板:
template <typename T>
using Vec = std::vector<T>;
int main() {
Vec<int> x;
}
这个语法比旧的更好(对于模板而言,实际上可以实现模板别名),但需要一个相当新的编译器。
__stdcall
部分可能会破坏您的代码(除非函数也被明确声明为 __stdcall
)。我建议只使用专有编译器扩展来保持默认调用约定,并且必须有充分的理由。#define
为 __stdcall
或其他取决于编译器的内容。尽管通常只在与具有定义调用约定的(通常是特定于平台的)库进行交互时才显式声明调用约定。 - Adam Rosenfield
start_address
是用来干什么的吗? - PlasmaHH