Peter VARGA
Peter VARGA

Reputation: 5186

std::forward_list.push_front(std::thread) fails to compile

this code fails to compile:

Class declaration:

class threadController
{
private:
    static std::forward_list<std::thread>   threadList;
    static std::mutex                       mutexThreadList;

public:
    static void startAndAddThreadToList(int argc, char * argv []);

};

Class definition:

std::forward_list<std::thread>  threadController::threadList;
std::mutex                      threadController::mutexThreadList;

void threadController::startAndAddThreadToList(int argc, char * argv [])
{
    // execute now the thread to avoid a delayed start because of the mutex lock
    std::thread threadInstance(threadCalculateOneInstrument, argc, argv);

    mutexThreadList.lock();
    threadList.push_front(threadInstance);
    mutexThreadList.unlock();
}

This is the compiler error:

/usr/local/include/c++/4.9.1/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::thread; _Args = {const std::thread&}; _Tp = std::thread]’:
/usr/local/include/c++/4.9.1/bits/alloc_traits.h:253:4:   required from ‘static std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::thread; _Args = {const std::thread&}; _Alloc = std::allocator<std::thread>; std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> = void]’
/usr/local/include/c++/4.9.1/bits/alloc_traits.h:399:57:   required from ‘static decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::thread; _Args = {const std::thread&}; _Alloc = std::allocator<std::thread>; decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) = <type error>]’
/usr/local/include/c++/4.9.1/bits/forward_list.h:357:42:   required from ‘std::_Fwd_list_base<_Tp, _Alloc>::_Node* std::_Fwd_list_base<_Tp, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::thread&}; _Tp = std::thread; _Alloc = std::allocator<std::thread>; std::_Fwd_list_base<_Tp, _Alloc>::_Node = std::_Fwd_list_node<std::thread>]’
/usr/local/include/c++/4.9.1/bits/forward_list.tcc:71:64:   required from ‘std::_Fwd_list_node_base* std::_Fwd_list_base<_Tp, _Alloc>::_M_insert_after(std::_Fwd_list_base<_Tp, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::thread&}; _Tp = std::thread; _Alloc = std::allocator<std::thread>; std::_Fwd_list_base<_Tp, _Alloc>::const_iterator = std::_Fwd_list_const_iterator<std::thread>]’
/usr/local/include/c++/4.9.1/bits/forward_list.h:803:9:   required from ‘void std::forward_list<_Tp, _Alloc>::push_front(const _Tp&) [with _Tp = std::thread; _Alloc = std::allocator<std::thread>]’
../source/threadController.cpp:27:38:   required from here
/usr/local/include/c++/4.9.1/ext/new_allocator.h:120:4: error: use of deleted function ‘std::thread::thread(const std::thread&)’

My intention is to implement a thread list. The threads run with indefinite execution time. A "control" thread is checking each 10 seconds the threads in the list. If a thread finished the thread function detach() is called for this thread in order to release the resources.

Upvotes: 1

Views: 471

Answers (2)

Galik
Galik

Reputation: 48635

It is not permitted to copy std::thread objects, you can use emplace like this:

threadList.emplace_front(threadCalculateOneInstrument, argc, argv);

See: std::forward_list::emplace_front().

Upvotes: 9

Anton Savin
Anton Savin

Reputation: 41321

std::threads are not copyable, you can either use emplace_front() as suggested by Galik, or insert rvalues (in this case move constructor will be invoked):

threadList.push_front(std::thread(threadCalculateOneInstrument, argc, argv));

This can be useful if you have a function which returns std::thread, so emplace_front() is not applicable:

std::thread createThread() {....}
threadList.push_front(createThread());

Upvotes: 2

Related Questions