我正在尝试编写一个可移植的线程抽象。现在我有一个编译dn的代码可以在Unix上运行但不能在Windows上编译(使用VS2010)。
class Thread
{
public:
Thread();
~Thread();
template<typename Callable, typename Arg>
void startThread(Callable c, Arg a);
void killThread();
private:
template<typename Bind>
struct nested
{
static DWORD WINAPI run(void *obj)
{
Bind * b = reinterpret_cast<Bind *>(obj);
return (b->exec());
}
};
template<typename Callable, typename Arg>
class Binder
{
public:
Binder(Callable c, Arg a): _call(c), _arg(a) {}
~Binder() {}
DWORD operator()() {return (this->_call(this->_arg))}
DWORD exec() {return (this->_call(this->_arg))}
private:
Callable _call;
Arg _arg;
};
HANDLE _handle;
DWORD _id;
bool _isRunning;
DWORD _exitValue;
};
template<typename Callable, typename Arg>
void Thread::startThread(Callable c, Arg a)
{
Thread::Binder<Callable, Arg> *b =
new Thread::Binder<Callable, Arg>(c, a);
CreateThread(0, 0,
Thread::nested< Thread::Binder<Callable, Arg> >::run,
b, 0, &this->_id);
}
当我尝试编译时,VS给了我一个错误C2039:
'nested<Thread::Binder<unsigned long (__cdecl*)(int *),int *> >' : is not a member of 'Thread'
为什么g ++会看到它而不是VS?大多数情况下,我认为这是因为模板专业化,但是怎么来?
答案 0 :(得分:0)
错误表明VS 2010在这种情况下无法区分类型和类成员。我不知道这是编译器错误还是代码中的错误。您可以通过更改代码来解决此问题,如下所示:
Thread::Binder<Callable, Arg> *b = new Thread::Binder<Callable, Arg>(c, a);
typedef Thread::nested<Thread::Binder<Callable, Arg> > MyBinder;
CreateThread(0, 0,
MyBinder::run,
b, 0, &this->_id);
在相关说明中,由于您使用的是CreateThread,请确保您了解“备注”部分中所述的相关措施。如果您打算使用线程中的C运行时库(CRT),请不要使用CreateThread。