【问题标题】:Static assertion failed error when trying to use std::vector<std::thread>尝试使用 std::vector<std::thread> 时出现静态断言失败错误
【发布时间】:2020-02-15 10:39:28
【问题描述】:

我有下面的类,它是头文件。当我在ProducerManager.h 中包含std::vector&lt;std::thread&gt; threads; 行时,我得到了这个问题底部显示的错误。我已经经历了多个 SO 问题,其中问题不是使用 std::move() 将线程移动到向量中,但是,显然因为我是通过右值来做的,所以它应该可以工作。但是我得到了这个我不明白的奇怪错误。谁能帮帮我?

// ProducerManager.h

#include <thread>
#include <queue>

#include "Producer.h"

class ProducerManager {
  public:
    ProducerManager(std::queue<std::string> *buffer, Semaphore *items);
    int run();
  private:
    std::queue<std::string> *buffer;
    Semaphore *items;
    bool empty_page_reached = false;
    unsigned int max_threads = 50;
    unsigned int num_pages = 0;
    std::vector<std::thread> threads;   // If I remove this line, I no longer get the error
    std::vector<Producer*> producers;
    std::queue<int> pids;
};

// ProducerManager.cc

#include "ProducerManager.h"

ProducerManager::ProducerManager(std::queue<std::string> *buffer, Semaphore *items) {
  this->buffer = buffer;
  this->items = items;
}

int ProducerManager::run(void) {
  ...
}

// main.cc

#include <string>
#include <thread>

#include "ProducerManager.h"
#include "Consumer.h"
#include "Semaphore.h"

int main(int argc, char *argv[]) {
  std::queue<std::string> *buffer = new std::queue<std::string>();
  Semaphore *items = new Semaphore(0);

  // Testing with just one consumer
  Consumer *c1 = new Consumer(buffer, items);
  std::thread cth1(&Consumer::perform, c1);

  ProducerManager pm(buffer, items);
  std::thread pm_thread(&ProducerManager::run, pm);

  pm_thread.join();
  cth1.join();

  delete c1;

  return 0;
}

错误:

/usr/include/c++/9.2.1/bits/stl_uninitialized.h: In instantiation of ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::thread*, std::vector<std::thread> >; _ForwardIterator = std::thread*]’:
/usr/include/c++/9.2.1/bits/stl_uninitialized.h:307:37:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::thread*, std::vector<std::thread> >; _ForwardIterator = std::thread*; _Tp = std::thread]’
/usr/include/c++/9.2.1/bits/stl_vector.h:555:31:   required from ‘std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = std::thread; _Alloc = std::allocator<std::thread>]’ProducerManager.h:6:7:   required from ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(_UHead&&) [with _UHead = ProducerManager&; long unsigned int _Idx = 1; _Head = ProducerManager]’/usr/include/c++/9.2.1/tuple:349:38:   required from ‘static std::thread::_Invoker<std::tuple<typename std::decay<_Tp>::type, typename std::decay<_Args>::type ...> > std::thread::__make_invoker(_Callable&&, _Args&& ...) [with _Callable = int (ProducerManager::*)(); _Args = {ProducerManager&}; typename std::decay<_Tp>::type = int (ProducerManager::*)()]’/usr/include/c++/9.2.1/thread:131:22:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = int (ProducerManager::*)(); _Args = {ProducerManager&}; <template-parameter-1-3> = void]’main.cc:17:50:   required from here
/usr/include/c++/9.2.1/bits/stl_uninitialized.h:127:72: error: static assertion failed: result type must be constructible from value type of input range  127 |       static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,

【问题讨论】:

  • 其中一个错误指向ProducerManager.h 第6 行,即#include&lt;Producer&gt;,另一个错误位于main。请包括minimal reproducible example
  • @idclev463035818 很抱歉。我已经包含了所有 Producer 和相关文件。我删除了不必要的部分并用...替换了它们。我测试了没有它们的编译是一样的。
  • 错误信息似乎是因为main.cc中触发了线程向量的复制构造函数
  • @nsm 它似乎来自ProducerManager pm(buffer, items)。我猜这是因为那是线程向量被初始化的时候。

标签: c++ multithreading c++11


【解决方案1】:

做起来

std::thread pm_thread(&ProducerManager::run, std::ref(pm));
// or
std::thread pm_thread(&ProducerManager::run, &pm);

std::thread 的构造函数按值接受参数。正如最初所写,它试图复制pm,但ProducerManager 不可复制(因为它的成员std::vector&lt;std::thread&gt; threads 不可复制,因为std::thread 不可复制)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    • 2013-07-21
    • 2019-10-27
    相关资源
    最近更新 更多