0

移植可能な Thread 抽象化を作成しようとしています。現在、Unix で動作する dn をコンパイルするコードがありますが、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 に答える