Try with
template<typename... T>
auto foo(T&&... t){
[](T&&... u){ }(std::forward<T>(t)...); // (1)
return std::thread( // (2)
[](auto &&... u){ },
std::forward<T>(t)...
);
}
I mean: in the lambda you pass to std::thread()
, auto && ...
instead of T && ...
. 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
template<typename... T>
auto foo(T&&... t)
the &&
are universal-references and T...
become int
, when you call foo(1)
, and int &
, when you call foo(n)
.
Inside the function you get
[](int){ }(std::forward<int>(t)); // (1)
return std::thread( // (2)
[](int){ },
std::forward<int>(t)...
);
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)
, inside foo()
you get
[](int &){ }(std::forward<int>(t)); // (1)
return std::thread( // (2)
[](int &){ },
std::forward<int>(t)...
);
and this works for the first call, because the lambda wait a int
left-reference variable (int &
) and get a int
left-reference variable, but doesn't works for the second call because std::thread
pass a copy of std::forward<int>(t)
(so a right-reference, int &&
) to the lambda that wait for a left-reference.