1

我正在尝试从同一个类中创建一个调用成员函数的线程。

我见过一些类似的问题,比如这个

但是,我的似乎不起作用。我得到一个错误,

std::thread arguments must be invocable after conversion to rvalues

使用此设置:

void MyClass::myFuncThread(
    const unsigned threadID,
    std::vector<myType*>& column,
    const unsigned x,
    const unsigned y) const
{
  // Each thread will write once to a single unique index of the vector, which should work 
  // despite vector not being thread-safe
  // Contents of this function omitted since it's not relevant to the error
}

void MyClass::myFunc(
    std::vector<myType*>& column,
    const unsigned x,
    const unsigned y) const
{
  column.resize(x, y);

  // Create a vector of threads
  std::vector<std::thread> threads;
  threads.resize(numThreads);

  // Launch all threads
  for (unsigned i = 0; i < threads.size(); i++)
    {
      threads[i] = std::thread(
          &MyClass::myFuncThread, this, i, column,
          x, y);
    }

  // Join all the threads
  for (unsigned i = 0; i < threads.size(); i++)
    {
      threads[i].join();
    }
}

这是我尝试编译时的完整错误:(用通用名称编辑)

/usr/include/c++/8/thread: In instantiation of ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (MyClass*)(unsigned int, std::vector<myType*>&, unsigned int, unsigned int) const; _Args = {const MyClass*, unsigned int&, std::vector<myType*>&, const unsigned int&, const unsigned int&}; <template-parameter-1-3> = void]’:
myclass.cpp:100:23:   required from here
/usr/include/c++/8/thread:120:17: error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues
  static_assert( __is_invocable<typename decay<_Callable>::type,
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           typename decay<_Args>::type...>::value,
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

它可能与参考有关。只有std::vector需要作为参考,其余的可以只是副本。std::ref()出于某种原因,我还需要包装一些东西吗?还是我只是std::thread以某种方式有错误的语法?出于某种原因,我是否需要使用“未来”和异步?

4

1 回答 1

4

它可能与参考有关。

这是。

出于某种原因,我还需要在 std::ref() 中包装一些东西吗?

是的。你需要使用std::ref.

围绕什么?

周围column

不会用 std::ref 包装它使其成为对引用的引用吗?

不能有std::reference_wrapper一个参考。该模板将被推断为std::reference_wrapper<std::vector<myType*>>您所需要的。

有用!我能问一下,为什么那里需要 std::ref() 吗?

因为,根据文档,std::thread复制其参数(如果可能,通过移动)。如果columnswhich 是向量的左值,则将制作向量的副本。副本作为右值传递给函数。非 const 左值引用(例如参数 is)不绑定到右值,因此程序格式错误。

它在完成什么?

std::reference_wrapper是一个可复制的对象,它在内部维护间接并隐式转换为被引用类型的左值,从而允许将其传递给引用参数。线程不会复制引用的向量,而是复制引用包装器。

你在这里推导出的模板是什么意思?

std::ref是一个函数模板。您不需要显式指定其模板参数,因为它可以从传递给它的参数推导出来。

PS 至少只要线程运行,请非常小心地保持引用的向量处于活动状态。

于 2020-01-09T18:15:06.400 回答