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.