Home > Back-end >  Can I move construct (or assign) to a map a different type values using conversion?
Can I move construct (or assign) to a map a different type values using conversion?

Time:12-08

I have a simple container for data (simplified more for the purpose of this question) that I use as a value in a map.

I want to know if there is some way I can move construct a map with this container as a value type from a map using the underlying data type.

Here is such a class:

class D
{
public:
    D() :m_value(0.0){}
    D(double value) : m_value(std::move(value)) {}
    D(const D& from) : m_value(from.m_value) {}
    D(D&& from) : m_value(std::move(from.m_value)) {}
    D& operator= (const D& from) { m_value = from.m_value; return *this; }
    D& operator= (D&& from) { m_value = std::move(from.m_value); return *this; }
    ~D() = default;

    double m_value;
};

And here is an example of how I would like to convert it.

int main() {
    std::map<std::string, double> m = { { "1", 1.0 } };

    std::map<std::string, D> m_map = std::move(m);

    return 0;
}

This gives the following error:

error C2440: 'initializing' : cannot convert from 'std::map<std::string,double,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,D,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'

I would like to note that the main reason I would like to move construct such a map, is to avoid creating copies of the key values of the map. Which in this case is a string.

CodePudding user response:

Something along these lines, perhaps (requires C 17):

std::map<Key, long> new_m;
while (!m.empty()) {
    auto node = m.extract(m.begin());
    new_m.emplace(std::move(node.key()), std::move(node.mapped()));
}

Demo. I made a user-defined class the key of the map rather than std::string, so that I could instrument it and confirm it's indeed being moved and not copied.

  • Related