hudac
hudac

Reputation: 2798

c++11 moving elements between list to map (or other containers)

Is there an easy way to move elements between different containers?
I couldn't find any simple way (using <algorithm>) to do the following:

Non copyable class

class NonCopyable {
public:
    NonCopyable() {};
    ~NonCopyable() {};
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable& operator=(const NonCopyable&) = delete;
    NonCopyable(NonCopyable&& that) {}
};

Move operations:

std::list<NonCopyable> eList;
std::map<int, NonCopyable> eMap;

eList.push_back(NonCopyable());

// Move from list to map
{
    auto e = std::move(eList.back());
    eList.pop_back();
    eMap.insert(std::make_pair(1, std::move(e)));
}

// Move from map to list
{
    auto it = eMap.find(1);
    if (it != eMap.end()) {
        eList.push_back(std::move(it->second));
        auto e = eMap.erase(it);
    }
}

// Move all
// Iterate over map?...

I've seen std::list::splice but it won't help me here because I have a list and a map, and not two lists...

Thanks

Upvotes: 1

Views: 756

Answers (2)

Grisha
Grisha

Reputation: 536

Well, you can just... move elements from one container to another in a cycle:

std::list<NonCopyable> lst;
// ...
std::map<std::size_t, NonCopyable> map;
for (auto& nc: lst) {
    map.emplace(map.size(), std::move(nc));
}
// use lst.clear() here, if you so inclined

Upvotes: 1

The Quantum Physicist
The Quantum Physicist

Reputation: 26356

How about std::move_iterator? Here's an example to move from vector to std::string

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <numeric>
#include <string>

int main()
{
    std::vector<std::string> v{"this", "is", "an", "example"};

    std::cout << "Old contents of the vector: ";
    for (auto& s : v)
        std::cout << '"' << s << "\" ";

    typedef std::vector<std::string>::iterator iter_t;
    std::string concat = std::accumulate(
                             std::move_iterator<iter_t>(v.begin()),
                             std::move_iterator<iter_t>(v.end()),
                             std::string());  // Can be simplified with std::make_move_iterator

    std::cout << "\nConcatenated as string: " << concat << '\n'
              << "New contents of the vector: ";
    for (auto& s : v)
        std::cout << '"' << s << "\" ";
    std::cout << '\n';
}

Output:

Old contents of the vector: "this" "is" "an" "example"
Concatenated as string: thisisanexample
New contents of the vector: "" "" "" ""

Upvotes: 2

Related Questions