0

我正在尝试编写一个可移植的线程抽象。现在我有一个编译 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 却看不到?大多数情况下,我认为这是因为模板专业化,但怎么会呢?

4

1 回答 1

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

于 2012-12-22T16:08:56.477 回答