简体   繁体   中英

Moving an std::unordered_map values to std::vector

Is there any way to move unordered_map values to a vector? All the ways I was able to find copy values (like in my example) instead of using something similar to std::move .

I would like to not copy values so I can retain uniqueness of shared_ptr foo, which I'll later change to unique_ptr .

class Class {
    public:
        std::shared_ptr <int> foo = std::shared_ptr <int> (new int (5));
};

int main() {
    std::unordered_map <int, Class> mapOfObjects({
                                                  {1, Class()},
                                                  {2, Class()},
                                                  {3, Class()},
                                                  {4, Class()},
                                                  {5, Class()} }); 
    std::vector <Class> someVector;

    for (auto &object : mapOfObjects) {

        someVector.push_back(object.second);
        std::cout << "Is unique?  " << ( someVector.back().foo.unique() ? "Yes." : "No.")                    
            << std::endl << std::endl;
    }  
}

Thank you in advance for all helpful answers.

You can certainly move shared_ptr from unordered_map to vector . All you need to do is to use std::move in your example:

someVector.push_back(std::move(object.second));

Keep in mind, after this operation, you might want to clear the map, as it now contains empty objects.

@SergeyA's answer already covers the essential part here, let me nevertheless add a solution based on range-v3 , it shows where one part of the language is heading to with C++20.

#include <range/v3/view/map.hpp>
#include <range/v3/view/move.hpp>

using namespace ranges;

/* Setup mapOfObjects... */

const std::vector<Class> someVector = mapOfObjects | view::values | view::move;

The STL in its current shape isn't that bad either, but admittetly more verbose:

#include <algorithm>
#include <iterator>

std::vector<Class> someVector;

std::transform(std::move_iterator(mapOfObjects.begin()),
        std::move_iterator(mapOfObjects.end()),
        std::back_inserter(someVector),
        [](std::pair<int, Class>&& entry){ return std::move(entry.second); });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM