从 class 成员函数构造 std::thread
Constructing a std::thread from a class member function
我想在 World::World()
中用 updateWorldLoop()
构造 updateThread
Chunk.h
class World
{
public:
static constexpr Chunk::Position renderSize = 10;
World();
//render chunks
void draw();
void drawDebug();
void enableUpdateThread();
void disableUpdateThread();
void updateWorldLoop();
private:
std::thread updateThread;
bool updateThreadShouldClose;
std::list<Chunk*> *frontDrawBuffer;
std::list<Chunk*> *backDrawBuffer;
std::list<Chunk*> unloadBuffer;
void loadChunk(Chunk::PosVec position);
};
Chunk.cpp
World::World() :
frontDrawBuffer(new std::list<Chunk*>),
backDrawBuffer(new std::list<Chunk*>),
unloadBuffer(),
updateThread(updateWorldLoop)
//ERROR: non-standard syntax; use '&' to create a pointer to member
{ /*Initialize textures*/}
我做了一些研究并尝试了几种方法。 None 他们工作了。
updateThread(&updateWorldLoop);
//ERROR: '&': illegal operation on bound member function expression
updateThread(this->updateWorldLoop);
//ERROR: non-standard syntax; use '&' to create a pointer to member
updateThread(&this->updateWorldLoop);
//ERROR: '&': illegal operation on bound member function expression
updateThread(World::updateWorldLoop);
//ERROR: non-standard syntax; use '&' to create a pointer to member
updateThread(&World::updateWorldLoop);
/***ERROR:
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(240): error C2672: 'std::invoke': no matching overloaded function found
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(248): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Execute<0>(std::tuple<void (__cdecl World::* )(void)> &,std::integer_sequence<_Ty,0>)' being compiled
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>,
1> _Ty=::size_t
1> ]
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(247): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Execute<0>(std::tuple<void (__cdecl World::* )(void)> &,std::integer_sequence<_Ty,0>)' being compiled
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>,
1> _Ty=::size_t
1> ]
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(244): note: while compiling class template member function 'void std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *) noexcept'
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>
1> ]
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(232): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *) noexcept' being compiled
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>
1> ]
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(259): note: see reference to class template instantiation 'std::_LaunchPad<_Target>' being compiled
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>
1> ]
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thread(49): note: see reference to function template instantiation 'void std::_Launch<std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<_Ty>>>(_Thrd_t *,_Target &&)' being compiled
1> with
1> [
1> _Ty=std::tuple<void (__cdecl World::* )(void)>,
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>
1> ]
1>d:\projects\blocky - opengl\src\chunk.cpp(339): note: see reference to function template instantiation 'std::thread::thread<void(__cdecl World::* )(void),,void>(_Fn &&)' being compiled
1> with
1> [
1> _Fn=void (__cdecl World::* )(void)
1> ]
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(240): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept(<expr>)'
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(240): note: With the following template arguments:
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(240): note: '_Callable=void (__cdecl World::* )(void)'
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(240): note: '_Types={}'
**/
此外,我尝试将所有成员置于 public:
范围内。没用。
您有两个个问题:
编译器的拳头甚至告诉你如何解决:你需要使用address-of运算符&
来获取指向成员函数的指针。
第二个问题是非静态成员函数需要调用一个对象,成为函数中的this
指针。创建线程时,它作为第一个参数传递(但实际上并未传递给函数)。
所以要解决你的两个问题,你的初始化程序需要看起来像
updateThread(&updateWorldLoop, this)
我想在 World::World()
updateWorldLoop()
构造 updateThread
Chunk.h
class World
{
public:
static constexpr Chunk::Position renderSize = 10;
World();
//render chunks
void draw();
void drawDebug();
void enableUpdateThread();
void disableUpdateThread();
void updateWorldLoop();
private:
std::thread updateThread;
bool updateThreadShouldClose;
std::list<Chunk*> *frontDrawBuffer;
std::list<Chunk*> *backDrawBuffer;
std::list<Chunk*> unloadBuffer;
void loadChunk(Chunk::PosVec position);
};
Chunk.cpp
World::World() :
frontDrawBuffer(new std::list<Chunk*>),
backDrawBuffer(new std::list<Chunk*>),
unloadBuffer(),
updateThread(updateWorldLoop)
//ERROR: non-standard syntax; use '&' to create a pointer to member
{ /*Initialize textures*/}
我做了一些研究并尝试了几种方法。 None 他们工作了。
updateThread(&updateWorldLoop);
//ERROR: '&': illegal operation on bound member function expression
updateThread(this->updateWorldLoop);
//ERROR: non-standard syntax; use '&' to create a pointer to member
updateThread(&this->updateWorldLoop);
//ERROR: '&': illegal operation on bound member function expression
updateThread(World::updateWorldLoop);
//ERROR: non-standard syntax; use '&' to create a pointer to member
updateThread(&World::updateWorldLoop);
/***ERROR:
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(240): error C2672: 'std::invoke': no matching overloaded function found
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(248): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Execute<0>(std::tuple<void (__cdecl World::* )(void)> &,std::integer_sequence<_Ty,0>)' being compiled
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>,
1> _Ty=::size_t
1> ]
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(247): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Execute<0>(std::tuple<void (__cdecl World::* )(void)> &,std::integer_sequence<_Ty,0>)' being compiled
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>,
1> _Ty=::size_t
1> ]
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(244): note: while compiling class template member function 'void std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *) noexcept'
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>
1> ]
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(232): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *) noexcept' being compiled
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>
1> ]
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(259): note: see reference to class template instantiation 'std::_LaunchPad<_Target>' being compiled
1> with
1> [
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>
1> ]
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thread(49): note: see reference to function template instantiation 'void std::_Launch<std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<_Ty>>>(_Thrd_t *,_Target &&)' being compiled
1> with
1> [
1> _Ty=std::tuple<void (__cdecl World::* )(void)>,
1> _Target=std::unique_ptr<std::tuple<void (__cdecl World::* )(void)>,std::default_delete<std::tuple<void (__cdecl World::* )(void)>>>
1> ]
1>d:\projects\blocky - opengl\src\chunk.cpp(339): note: see reference to function template instantiation 'std::thread::thread<void(__cdecl World::* )(void),,void>(_Fn &&)' being compiled
1> with
1> [
1> _Fn=void (__cdecl World::* )(void)
1> ]
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(240): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept(<expr>)'
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(240): note: With the following template arguments:
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(240): note: '_Callable=void (__cdecl World::* )(void)'
1>c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.10.25017\include\thr\xthread(240): note: '_Types={}'
**/
此外,我尝试将所有成员置于 public:
范围内。没用。
您有两个个问题:
编译器的拳头甚至告诉你如何解决:你需要使用address-of运算符
&
来获取指向成员函数的指针。第二个问题是非静态成员函数需要调用一个对象,成为函数中的
this
指针。创建线程时,它作为第一个参数传递(但实际上并未传递给函数)。
所以要解决你的两个问题,你的初始化程序需要看起来像
updateThread(&updateWorldLoop, this)