1. 程式人生 > >C++ Thread類報錯

C++ Thread類報錯

#include <thread>
#include <iostream>
void start_thread(int& param) {
    std::cout << param << std::endl;
}
int main() {
    int value(7);
    std::thread mythread(start_thread, value);
    
    mythread.join();
    
    return 0;
}

乍看之下,有一個“引用包裝器”,而不是一個普通的舊引用似乎沒有什麼用處。它的直接用處被這樣一個事實所掩蓋:它只有在使用像C ++ 11一樣新增的其他新特性(如

std::bindstd::thread )時才真正有用。std::ref是一種解決方法,用於模板型別推導規則推導引數型別的情況,以便引數按值取值,而意圖是通過引用來取引數。

報錯資訊類似:

In file included from /usr/include/c++/5.3.0/thread:39:0,
                 from main.cpp:1:
/usr/include/c++/5.3.0/functional: In instantiation of ‘struct std::_Bind_simple<void (*(int))(int&)>’:
/usr/include/c++/5.3.0/thread:137:59:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(int&); _Args = {int&}]’
main.cpp:11:45:   required from here
/usr/include/c++/5.3.0/functional:1505:61: error: no type named ‘type’ in ‘class std::result_of<void (*(int))(int&)>’
       typedef typename result_of<_Callable(_Args...)>::type result_type;
                                                             ^
/usr/include/c++/5.3.0/functional:1526:9: error: no type named ‘type’ in ‘class std::result_of<void (*(int))(int&)>’
         _M_invoke(_Index_tuple<_Indices...>)
         ^

忽略這裡明顯的設計缺陷;這個例子只是為了演示當你嘗試傳遞一個值引數時引用從std::thread::thread()等模板函式呼叫的函式時會發生什麼。請注意,模板型別推導(正確)推導值的型別為int ,但這不符合它在start_thread中看到的int&型別。編譯器給出的實際錯誤(在這種情況下為GCC)實際上比這更為模糊:

編譯器確實表明,錯誤隱約與將函式引數繫結到傳入的函式有關; 使用指向std::ref的錯誤中的關鍵字作為解決方案進行線上快速搜尋。

那麼std::ref如何通過引用將引數傳遞給引數型別按值推導的模板函式?std::reference_wrapper (由std::ref

返回的型別)及其libstdc ++ 文件 / 原始碼的定義描繪了一幅非常清晰的圖片。 std::reference_wrapper只是一個隱式地轉換為引用的指標的薄包裝(通過operator T&() const ):

所以模板函式中引數的推導型別是std::reference_wrapper<T> (在上面的例子中是std::reference_wrapper<int> ),它可以通過值傳遞給函式。這與參考大小相同,當它傳遞給另一個需要引數的函式時,它會隱式轉換為一個引數。所以在功能上,它聞起來很像一個參考。讓我們看看它的行動:


#include <thread>
#include <iostream>
#include <functional>
void start_thread(int& param) {
    std::cout << param << std::endl;
}
int main() {
    int value(7);
    std::thread mythread(start_thread, std::ref(value));
    
    mythread.join();
    
    return 0;
}

output:7