【问题标题】:Templated nested class not found C++未找到模板化嵌套类 C++
【发布时间】:2012-12-22 15:20:21
【问题描述】:

我正在尝试编写一个可移植的线程抽象。现在我有一个编译 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&lt;Thread::Binder&lt;unsigned long (__cdecl*)(int *),int *&gt; &gt;' : is not a member of 'Thread'

g++怎么能看到VS却看不到呢?大多数情况下,我认为这是因为模板专业化,但这是怎么回事?

【问题讨论】:

  • 我在这里没有看到任何专业化。
  • 此代码无法在 Fedora 14 上使用 g++ 4.5.1 进行编译。test.c:47:26: error: ‘class Thread’ has no member named ‘_id’
  • 这段代码显然是windows版本,除非你把DWORD改成int,否则它不会在Fedora上编译。
  • 由于我无法编辑您的帖子,请修正Binder::operator()Binder::exec() 中的语法错误。

标签: c++ windows class templates nested


【解决方案1】:

该错误表明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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-08
    • 2016-01-11
    • 2011-05-04
    • 2017-02-05
    • 2016-08-08
    • 2016-04-12
    • 2018-11-26
    • 1970-01-01
    相关资源
    最近更新 更多