2016-04-15 60 views
0

如何使用通用lambda來創建線程並將自動參數定義爲引用?從通用lambdas創建線程並將引用作爲通用參數

舉例來說,這將是實現概念上等同於這個事情的正確方法:

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); 

回答

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); 

在這種情況下,汽車& &被推斷,好像它是一個模板參數。因此,實例化過程中的實際類型是根據需要const T&T&&

+1

是的,它實際上是一個很好的例子,爲什麼'汽車'很少有意義。它可以是'auto'或'auto &&'。 – SergeyA

+0

@SergeyA你有什麼有意義的例子,汽車和有意義嗎? –

1

問題在於它試圖從std::reference_wrapper<int>類型的右值導出auto&,並且無法這樣做,因爲非常量左值引用不能從右值導出。只有當目標函數有一個已知類型的引用(意味着沒有推導,並應用reference_wrapper的轉換運算符)或非引用類型(意味着不需要轉換)時才起作用。

+0

根據你的說法,它聽起來像'std :: thread([](int&v){},std :: ref(vi));'也不應該。我誤解了什麼嗎? –

+2

@ComeRaczy,是的,你做錯了。在你的例子中沒有**扣除**,但只是從'std :: ref'到左值引用的轉換,這很好地工作。 – SergeyA