Search code examples
c++c++11concurrencyvisual-studio-2013ppl

Converting concurrent_vector to std::vector


I'm looking for the recommended way to convert a concurrent_vector from the PPL library to a normal std::vector.

I have a function which returns its results in a std::vector but may or may not use parallel algorithms internally. Currently I'm using insert to copy the elements from the concurrent vector to the normal vector:

#ifdef PARALLEL
    std::vector<Foo> Bar() {
        concurrency::concurrent_vector<Foo> cv;

        //Fill cv in a parallel algorithm

        std::vector<Foo> sv;
        sv.insert(sv.begin(), cv.begin(), cv.end());
        return sv;
    }
#else
    std::vector<Foo> Bar() {
        std::vector<Foo> sv;

        //Fill sv in a sequential algorithm

        return sv;
    }
#endif

Although the performance of the insert operation is not a real issu at the moment (compared to the function body), it just seems unnecessary and I wonder whether there is a better solution (Btw.: Foo is a simple POD which cannot be moved).

Ideally I would like to have something similar to this

std::vector<Foo> Bar() {
    concurrency::concurrent_vector<Foo> cv;

    //Fill cv in a parallel algorithm

    return static_cast<std::vector<Foo>>(cv);
}

or at least

std::vector<Foo> Bar() {
    concurrency::concurrent_vector<Foo> cv;

    //Fill cv in a parallel algorithm

    std::vector<Foo> sv(std::move(cv));
    return sv;
}

Are there any suggestions on how to do this properly?


EDIT:
As always I overlooked the most obvious simplification (suggested by Chris):

std::vector<Foo> Bar() {
    concurrency::concurrent_vector<Foo> cv;

    //Fill cv in a parallel algorithm

    return std::vector<Foo>(cv.begin(), cv.end());
}

while it (most probably) doesn't get rid of the copies it looks much cleaner.

EDIT2:

This leads me to the qestion of - assuming there is no way to explicitly prevent a copy of the vector data - how likely it is that the compiler can optimize the copy (from concurrent to std::vector) away, while still applying RVO or a move operation on the functions' return value


Solution

  • assuming there is no way to explicitly prevent a copy of the vector data - how likely it is that the compiler can optimize the copy (from concurrent to std::vector) away, while still applying RVO or a move operation on the functions' return value?

    concurrent_vector is quite different from std::vector. In particular, its data storage is not contiguous in memory, as std::vector requires. Thus the conversion you seek for is impossible, whether explicit or as a compiler optimization; data need to be copied from one location to another.