std::thread
's destructor will call std::terminate
if the thread has not been joined or detached.
So unfortunately you cannot create an anonymous thread object like this - you need a reference to the thread
object in order to call either join()
or detach()
.
Scott Meyers gave a talk at Going Native 2013 where he created an RAII class that wraps a thread and calls join in the destructor. You could do something similar:
class ThreadRAII {
public:
ThreadRAII(std::thread&& thread): t(std::move(thread)) {}
~ThreadRAII() { if (t.joinable()) { t.join(); }
private:
std::thread t;
};
See his blog post or talk for more info.
You could use it like this
(ThreadRAII(std::thread(Foo)));
However, the only reason you'd want to create a thread in this way is if you don't care when (or if) it ends, so in this case, join doesn't make much sense. You should modify the destructor to detach instead:
~ThreadRAII() { if (t.joinable()) { t.detach(); }
As suggested in the comments, you could make it even easier to use by perfect forwarding to an internal thread on construction:
class ThreadRAII2 {
public:
template <typename Func, typename ...Args>
explicit ThreadRAII2(Func&& func, Args&&... args) :
t(func, std::forward<Args>(args)...) { }
~ThreadRAII2() {
if (t.joinable()) t.detach();
}
private:
std::thread t;
};
Then you can use it just like you originally wanted to, no detach necessary:
(ThreadRAII2(Foo));
Or, if Foo
takes arguments (for example Foo(int)
):
(ThreadRAII2(Foo, 42));