General Category > General Discussion about just::thread

std::vector<std::thread> example from Concurrency in action

(1/2) > >>

Kenneth Carter:
Error   4   
error C2558: class 'std::thread' : no copy constructor available or copy constructor is declared 'explicit'
f:\program files (x86)\microsoft visual studio 9.0\vc\include\vector   line 1211

I recently aquired your book and was reading through. and I tried using a std::vector with the just::thread class.

Kenneth

Anthony Williams:

--- Quote from: Kenneth Carter on November 21, 2008, 06:46:43 PM ---Error   4   
error C2558: class 'std::thread' : no copy constructor available or copy constructor is declared 'explicit'
f:\program files (x86)\microsoft visual studio 9.0\vc\include\vector   line 1211

--- End quote ---

std::thread is movable, but not copyable. This means that you need a move-aware container to be able to store it --- none of the containers shipped with MSVC 2008 are move aware, because every movable-but-not-copyable type does it it's own way. In C++0x move semantics is supported with rvalue references (see my blog entry at http://www.justsoftwaresolutions.co.uk/cplusplus/rvalue_references_and_perfect_forwarding.html), and the standard library containers will have to support such types. For now, we have to write our own.


--- Quote ---I recently aquired your book and was reading through. and I tried using a std::vector with the just::thread class.

--- End quote ---

Thanks for reading. Not all the examples can be made to work, unfortunately.

Kenneth Carter:
Does the below code satisfy the condition with vector? it compiles but I have not executed the code at this time.   

    std::vector<std::thread>    threads( num_threads - 1 );
    std::vector<T>                 results( num_threads );
   
    // iterate the thread array and send chunks of data into the threads
    iterator block_start    = first;
    for( unsigned long i = 0; i < ( num_threads - 1 ); ++i )
    {
        iterator block_end  = block_start;
        std::advance(block_end, block_size);
        threads = std::move( std::thread( //<-- this compiles
            accumulate_block<iterator, T>(),
            block_start,
            block_end,
            std::ref( results ) ) );
        block_start = block_end;
    }

Anthony Williams:
Your example looks like it should work. Only functions that resize a vector or otherwise copy elements require the contained type to be copyable (so that's resize, push_back, erase, insert, copy-construction and copy assignment of the vector, swap and reserve).

If you know the size of your vector up front then you can pre-allocate it and use move-assignment, as in your example. My previous blanket statement was a bit of a generalization.

Kenneth Carter:
the above sample would still not work. what I have found that works if I use a raw array pointer of std::thread *ptr_threads = new std::thread[ num_threads - 1 ].

the only draw back is that I have to remember to clean it up with delete [] ptr_threads.

Kenneth

Navigation

[0] Message Index

[#] Next page

Go to full version