I have the below class and it's header file. When I include the line std::vector<std::thread> threads;
in ProducerManager.h
, I get the error shown at the bottom of this question. I have gone through multiple SO questions where the issue was not using std::move() to move the thread into the vector, however, apparently since I am doing it by rvalue it should work. But I get this weird error I don't understand. Could anyone be so kind as to help me out?
// 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) {
// Create initial threads
for (unsigned int i = 0; i < max_threads; i++) {
producers.push_back(new Producer("http://example.com/stuff.json?page="+std::to_string(i+1), i+1, buffer, items, &pids, &empty_page_reached));
threads.push_back(std::thread(&Producer::perform, producers[i]));
num_pages++;
}
// Keep respawning threads while we haven't yet found an empty page
while(!empty_page_reached) {
if (!pids.empty()) {
// Replace the thread corresponding to a finished page number
int idx = pids.front() - 1;
threads[idx].join();
delete producers[idx];
producers[idx] = new Producer("http://example.com/stuff.json?page="+std::to_string(num_pages+1), num_pages+1, buffer, items, &pids, &empty_page_reached);
threads[idx] = std::thread(&Producer::perform, producers[idx]);
pids.pop();
num_pages++;
}
}
// Clean up all remaining threads
while(!pids.empty()) {
int idx = pids.front() - 1;
threads[idx].join();
delete producers[idx];
pids.pop();
num_pages++;
}
return num_pages;
}
Error:
/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,
Aucun commentaire:
Enregistrer un commentaire