I'm having trouble finding how use std::thread()
with lambdas. Namely, with having a variadic argument lambda receive the arguments by forwarding. As an example:
template<typename... T>
auto foo(T&&... t){
[](T&&... t){}(std::forward<T>(t)...); // (1)
return std::thread( // (2)
[](T&&... t){},
std::forward<T>(t)...
);
}
auto bar(){
int n=1;
foo(1); (A)
foo(n); (B)
}
A.1: compiles
A.2: compiles
B.1: compiles
B.2: doesn't compile
I don't understand:
- Why the
std::thread()
(2) version using (B) doesn't compile and (A.2) does? - Why are there differences between (B.1) and (B.2)
Try with
I mean: in the lambda you pass to
std::thread()
,auto && ...
instead ofT && ...
. Or, maybe,T const & ...
.I'm not a language layer, and maybe someone can correct me, but it seems to me that there is a clash between universal references and r-value references. And the fact that
std::thread()
pass copies of the following arguments to the first one.When you write
the
&&
are universal-references andT...
becomeint
, when you callfoo(1)
, andint &
, when you callfoo(n)
.Inside the function you get
in case
f(0)
.And this works because both lambda are waiting a
int
by copy and this ever works.But when you call
f(n)
, insidefoo()
you getand this works for the first call, because the lambda wait a
int
left-reference variable (int &
) and get aint
left-reference variable, but doesn't works for the second call becausestd::thread
pass a copy ofstd::forward<int>(t)
(so a right-reference,int &&
) to the lambda that wait for a left-reference.