The following program does not build in GCC 4.9.2 or clang 3.6:
#include <iostream>
#include <vector>
#include <thread>
/* Non-copyable type */
struct Foo {
Foo() {};
Foo(const Foo &) = delete;
Foo &operator=(const Foo &) = delete;
Foo(Foo &&) = default; //EDIT: This fixes CASE 1
};
/* Bar depends on Foo */
struct Bar {
Bar(const Foo &) {}
};
template <class T, class... Args>
void my_function(Args &&... args) {
std::vector<T> data;
auto lambda = [&data](Args &&... ts) { data.emplace_back(ts...); };
lambda(std::forward<Args>(args)...); // <-- Compile
std::thread(lambda, std::forward<Args>(args)...); //<--- Does NOT compile
}
int main() {
//CASE 1: (works)
// my_function<Bar>(Foo());
//CASE 2: (does not work)
Foo my_foo;
my_function<Bar>(my_foo);
}
This is because Foo is not copyable and forwarding an instance of Foo to an std:thread attempts to copy it (why?). However, if you forward the same instance to the lambda directly it compiles.
I guess, I don't fully understand all the requirements of the std::thread constructor. Any help would be greatly appreciated.
EDIT: Case 2 does not work even if we make Foo movable. Any clue?
Thanks.
std::thread's constructor makes a copy because the alternative would be way too error prone (it would be way too easy to cause dangling references and data races). If you don't want a copy, then use areference_wrapper, or make the lambda also captureargsby reference. - T.C.std::refand reference wrapper -- but that is silly in this context, as the reference must last beyond the thread's lifetime. - Yakk - Adam Nevraumontshared_ptrto hold the noncopyable instance. - Siyuan Ren