My company is using it´s own thread API and I am not allowed to use std::thread, so I want to create a class to wrap our legacy API. I am not sure how to pass a r-value reference to my TestThread::ThreadUpdateLoop (see below code) so I stored it as a member variable. Is this ok or undefined behavior? Can I some how pass the r-value to the update function without storing it as a member?
template<typename TOwner>
class ScopedLegacyThread
{
public:
ScopedLegacyThread(ScopedLegacyThread& other) = delete;
ScopedLegacyThread& operator=(ScopedLegacyThread& other) = delete;
using ThreadCallbackFunc = void(TOwner::*)(void);
public:
ScopedLegacyThread(const char* thread_name, TOwner* owner, void(TOwner::* callback)(void))
: m_Owner(owner),
m_ThreadCallback(callback)
{
m_Thread = ThreadCreate(thread_name, ThreadCallback, this, 4096);
}
~ScopedLegacyThread()
{
if (IsJoinable())
{
Join();
}
}
bool IsJoinable() const
{
return ThreadGetID(m_Thread) != 0;
}
void Join()
{
ThreadJoin(m_Thread);
}
private:
static void ThreadCallback(void* args_ptr)
{
ScopedLegacyThread<TOwner>* scoped_thread =
(ScopedLegacyThread<TOwner>*)args_ptr;
ThreadCallbackFunc callback = scoped_thread->m_ThreadCallback;
(scoped_thread->m_Owner->*callback)();
}
private:
TOwner* m_Owner;
ThreadCallbackFunc m_ThreadCallback;
HThread m_Thread{ nullptr };
};
struct SomeConfig
{
std::unique_ptr<int> m_Value;
};
class TestThread
{
public:
explicit TestThread(SomeConfig&& config)
: m_Config(std::forward<SomeConfig>(config)),
m_ScopedThread("test thread", this, &TestThread::ThreadUpdateLoop)
{}
public:
void ThreadUpdateLoop()
{
int v = *m_Config.m_Value; // accessing my r-value reference member is this ok?
}
private:
SomeConfig&& m_Config; // r-value reference member!?
ScopedLegacyThread<TestThread> m_ScopedThread;
};
main(int argc, char** argv)
{
SomeConfig config;
config.m_Value = std::make_unique<int>(10);
CTestThread thread(std::forward<SomeConfig>(config));
return 0;
}