为什么线程函数的参数是ref,编译器失败?

时间:2019-11-20 15:27:27

标签: multithreading c++11 reference

使用线程库时,我对ref作为参数感到困惑,下面是代码:

#include "../include.h"  // include some header file
class A { 
 public:
  A(unordered_map<int, int>& m) : m(m) {  
  }
  void Start() {
    std::thread(test1, m); 
  }
 private:
  static void test1(unordered_map<int, int>&  m) {  // complie failed, if the ref change to value(remove &), it's ok, thats confused me
    for (auto i : m) {
      cout << i.first << i.second << endl;
    }   
  }
  unordered_map<int, int> & m;
};

int main() {
  unordered_map<int, int> m = {{1,2}, {3,4}};
  A a(m);
  a.Start();
}

当我让test1的参数为ref时,它失败了,并出现了很多味精:

In file included from /usr/include/c++/4.8.2/thread:39:0,
                 from ./../include.h:6,
                 from ./test@classref.cpp:1:
/usr/include/c++/4.8.2/functional: In instantiation of ‘struct std::_Bind_simple<void (*(std::unordered_map<int, int>))(std::unordered_map<int, int>&)>’:
/usr/include/c++/4.8.2/thread:137:47:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(std::unordered_map<int, int>&); _Args = {std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<const int, int> > >&}]’
./test@classref.cpp:10:25:   required from here
/usr/include/c++/4.8.2/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of<void (*(std::unordered_map<int, int>))(std::unordered_map<int, int>&)>’
       typedef typename result_of<_Callable(_Args...)>::type result_type;
                                                             ^
/usr/include/c++/4.8.2/functional:1727:9: error: no type named ‘type’ in ‘class std::result_of<void (*(std::unordered_map<int, int>))(std::unordered_map<int, int>&)>’
         _M_invoke(_Index_tuple<_Indices...>)
         ^

但是如果参数是有价值的,那很好,我不知道区别,有人可以帮忙吗?

关于线程函数参数,有什么我不知道的特别之处吗? 非常感谢。

1 个答案:

答案 0 :(得分:2)

cppreference

  

线程函数的参数按值移动或复制。如果   一个引用参数需要传递给线程函数,它具有   要包装(例如,使用std :: ref或std :: cref)。

所以

  void Start() {
    auto t = std::thread(test1, std::ref(m)); 
    t.join(); // so it waits for the thread to finish printing for your example.
  }

Demo