如何使用定义为引用的自动参数的通用lambda创建线程?
例如,实现概念上等同于此的东西的正确方法是什么:
int vi = 0;
auto lambda = [](auto &v) {};
auto t = std::thread(lambda, std::ref(vi));
gcc-5.3由于缺少类型而抱怨:
/opt/gcc/el6/gcc-5.3.0/include/c++/5.3.0/functional: In instantiation of ‘struct std::_Bind_simple<main()::<lambda(auto:2&)>(std::reference_wrapper<int>)>’:
/opt/gcc/el6/gcc-5.3.0/include/c++/5.3.0/thread:137:59: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = main()::<lambda(auto:2&)>&; _Args = {std::reference_wrapper<int>}]’
testLambdaCapture.cpp:52:41: required from here
/opt/gcc/el6/gcc-5.3.0/include/c++/5.3.0/functional:1505:61: error: no type named ‘type’ in ‘class std::result_of<main()::<lambda(auto:2&)>(std::reference_wrapper<int>)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/opt/gcc/el6/gcc-5.3.0/include/c++/5.3.0/functional:1526:9: error: no type named ‘type’ in ‘class std::result_of<main()::<lambda(auto:2&)>(std::reference_wrapper<int>)>’
_M_invoke(_Index_tuple<_Indices...>)
^
作为一个附带问题,为什么当泛型参数按照这样的值传递时它才起作用:
auto lambda = [](auto v) {};
auto t = std::thread(lambda, vi);
答案 0 :(得分:2)
固定:
#include <thread>
int vi = 0;
auto lambda = [](auto &&v) {};
auto t = std::thread(lambda, std::ref(vi));
// this works too
auto rv = std::ref(vi);
auto t2 = std::thread(lambda, rv);
在这种情况下,auto&amp;&amp;被推断为好像它是一个模板参数。因此,实例化期间的实际类型可以是const T&
或T&&
。
答案 1 :(得分:1)
问题是它试图从类型auto&
的右值中推导出std::reference_wrapper<int>
而没有这样做,因为不能从rvalues中推导出非常量左值引用。只有当目标函数具有对已知类型的引用(意味着没有推论,并且reference_wrapper
的转换运算符适用)或非引用类型(意味着不需要转换)时,它才有效。