C++ C++;方法线程

C++ C++;方法线程,c++,c++11,C++,C++11,我想为类中的方法创建一个线程。我写过这样的话: class Program { public: Program(); void render(); }; Program::Program() { thread t(render); } void Program::render() { cout << "Hello" << endl; } 它说: 1>c:\program files(x86)\micros

我想为类中的方法创建一个线程。我写过这样的话:

class Program
{
    public:
        Program();
        void render();
};

Program::Program()
{
    thread t(render);
}

void Program::render()
{
    cout << "Hello" << endl;
}
它说:

1>c:\program files(x86)\microsoft visual studio 12.0\vc\include\functional(1149) : error C2064 : term does not evaluate to a function taking 0 arguments
1>          class does not define an 'operator()' or a user defined conversion operator to a pointer - to - function or reference - to - function that takes appropriate number of arguments
1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\functional(1137) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Program::* )(void),void,Program,>,>::_Do_call<,>(std::tuple<>,std::_Arg_idx<>)' being compiled
1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\functional(1137) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Program::* )(void),void,Program,>,>::_Do_call<,>(std::tuple<>,std::_Arg_idx<>)' being compiled
1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(195) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Program::* )(void),void,Program,>,>::operator ()<>(void)' being compiled
1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(195) : see reference to function template instantiation 'void std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Program::* )(void),void,Program,>,>::operator ()<>(void)' being compiled
1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(192) : while compiling class template member function 'unsigned int std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *)'
1>          with
1>[
    1>              _Target = std::_Bind<true, void, std::_Pmf_wrap<void(__thiscall Program::*)(void), void, Program, >, >
        1>]
        1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(187) : see reference to function template instantiation 'unsigned int std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *)' being compiled
        1>          with
        1>[
            1>              _Target = std::_Bind<true, void, std::_Pmf_wrap<void(__thiscall Program::*)(void), void, Program, >, >
                1>]
                1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(205) : see reference to class template instantiation 'std::_LaunchPad<_Target>' being compiled
                1>          with
                1>[
                    1>              _Target = std::_Bind<true, void, std::_Pmf_wrap<void(__thiscall Program::*)(void), void, Program, >, >
                        1>]
                        1>          c:\program files(x86)\microsoft visual studio 12.0\vc\include\thread(49) : see reference to function template instantiation 'void std::_Launch<std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall Program::* )(void),void,Program,>,>>(_Thrd_t *,_Target &&)' being compiled
                        1>          with
                        1>[
                            1>              _Target = std::_Bind<true, void, std::_Pmf_wrap<void(__thiscall Program::*)(void), void, Program, >, >
                                1>]
                                1>          c:\users\erik\documents\visual studio 2013\projects\c++gameengine\c++gameengine\program.cpp(16) : see reference to function template instantiation 'std::thread::thread<void(__thiscall Program::* )(void),>(_Fn &&)' being compiled
                                1>          with
                                1>[
                                    1>              _Fn = void(__thiscall Program::*)(void)
                                        1>]
1>c:\program files(x86)\microsoft visual studio 12.0\vc\include\functional(1149):错误C2064:term不计算为包含0个参数的函数
1> 类不定义“operator()”或用户定义的转换运算符,以指向具有适当数量参数的函数指针或函数引用
1> c:\ProgramFiles(x86)\microsoft visual studio 12.0\vc\include\functional(1137):请参阅正在编译的函数模板实例化“void std::_Bind::_Do_call(std::tuple,std:_Arg_idx)”的参考
1> c:\ProgramFiles(x86)\microsoft visual studio 12.0\vc\include\functional(1137):请参阅正在编译的函数模板实例化“void std::_Bind::_Do_call(std::tuple,std:_Arg_idx)”的参考
1> c:\ProgramFiles(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(195):请参阅正在编译的函数模板实例化“void std::_Bind::operator()(void)”的参考
1> c:\ProgramFiles(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(195):请参阅正在编译的函数模板实例化“void std::_Bind::operator()(void)”的参考
1> c:\ProgramFiles(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(192):编译类模板成员函数“unsigned int std::_LaunchPad::_Run(std:_LaunchPad*)”
1> 与
1>[
1> _Target=std::_Bind
1>]
1> c:\ProgramFiles(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(187):请参阅正在编译的函数模板实例化“unsigned int std::_LaunchPad::_Run(std:_LaunchPad*)”的参考
1> 与
1>[
1> _Target=std::_Bind
1>]
1> c:\ProgramFiles(x86)\microsoft visual studio 12.0\vc\include\thr\xthread(205):请参阅正在编译的类模板实例化“std::\u LaunchPad”的参考
1> 与
1>[
1> _Target=std::_Bind
1>]
1> c:\ProgramFiles(x86)\microsoft visual studio 12.0\vc\include\thread(49):请参阅正在编译的函数模板实例化“void std::”的参考
1> 与
1>[
1> _Target=std::_Bind
1>]
1> c:\users\erik\documents\visualstudio 2013\projects\c++gameengine\c++gameengine\program.cpp(16):请参阅正在编译的函数模板实例化“std::thread::thread(_Fn&)”
1> 与
1>[
1> \u Fn=void(\u thiscall程序::*)(void)
1>]

我不太明白怎么了。您能解释一下并给我一个解决方案吗?

您应该使您的类成员函数
为静态的
,或者使用将函数传递给
std::thread
实例


还要注意你的
std::thread t变量是构造函数的本地变量。通过这种方式,您将失去与该线程的任何连接,并且在构造函数的作用域结束后不再对其进行控制。

您应该将类成员函数设置为静态的,或者使用将函数传递给
std::thread
实例

还要注意你的
std::thread t变量是构造函数的本地变量。通过这种方式,您将失去与该线程的任何连接,并且在构造函数的作用域结束后不再对其进行控制。

您可以这样做:

Program::Program()
{
    std::thread t(&Program::render, this);
    t.join();
}
然而,这并没有实现什么,因为它只是阻塞直到函数调用返回。也许你想拆线

std::thread(&Program::render, this).detach();
现在,您需要构建自己的逻辑来告诉线程何时停止

或者使线程成为类成员:

struct Program
{
    void render();

    Program() : render_thread_(&Program::render, this) {}
    ~Program() { render_thread_.join(); }

    std::thread render_thread_;
};
您可以这样做:

Program::Program()
{
    std::thread t(&Program::render, this);
    t.join();
}
然而,这并没有实现什么,因为它只是阻塞直到函数调用返回。也许你想拆线

std::thread(&Program::render, this).detach();
现在,您需要构建自己的逻辑来告诉线程何时停止

或者使线程成为类成员:

struct Program
{
    void render();

    Program() : render_thread_(&Program::render, this) {}
    ~Program() { render_thread_.join(); }

    std::thread render_thread_;
};

render
是一个非静态成员函数,因此需要一个对象来调用它。您需要将它封装在一个小函数对象中,以便在
程序中调用它。根据口味,有两种方便的方法:

thread t(&Program::render, this);
thread t([this]{render();});

下一个问题是线程是构造函数的本地线程,因此会立即被销毁。在未连接(等待线程完成)或分离线程对象之前,不能销毁线程对象。因此,要么让它成为一个成员,这样你以后就可以加入它;或者在返回之前将其分离。

render
是一个非静态成员函数,因此它需要一个对象来调用它。您需要将它封装在一个小函数对象中,以便在
程序中调用它。根据口味,有两种方便的方法:

thread t(&Program::render, this);
thread t([this]{render();});

下一个问题是线程是构造函数的本地线程,因此会立即被销毁。在未连接(等待线程完成)或分离线程对象之前,不能销毁线程对象。因此,要么让它成为一个成员,这样你以后就可以加入它;或者在返回之前将其分离。

不需要
bind
,它有一个可变构造函数。或者可变构造函数
线程t(&Program::render,this)
,随便你喜欢。不需要
bind
,它有一个可变构造函数。或者可变构造函数
线程t(&Program::render,this)
,随便你喜欢哪个。我为什么要参加呢?当函数返回时,它不应该停止吗?@ErikW:因为这些是规则。没有办法去看电影