Stealing resources from std::map's keys allowed?

You're doing undefined behavior, using const_cast to modify a const variable. Don't do that. The reason it's const is because maps are sorted by their keys. So modifying a key in-place is breaking the underlying assumption the map is built on.

You should never use const_cast to remove const from a variable and modify that variable.

That being said, C++17 has the solution for your problem: std::map's extract function:

#include <map>
#include <string>
#include <vector>
#include <utility>

int main() {
  std::vector<std::pair<std::string, double>> v;
  std::map<std::string, double> m{{"aLongString", 1.0},
                                  {"anotherLongString", 2.0}};

  auto extracted_value = m.extract("aLongString");
  v.emplace_back(std::make_pair(std::move(extracted_value.key()),
                                std::move(extracted_value.mapped())));

  extracted_value = m.extract("anotherLongString");
  v.emplace_back(std::make_pair(std::move(extracted_value.key()),
                                std::move(extracted_value.mapped())));
}

And don't using namespace std;. :)


Your code attempts to modify const objects, so it has undefined behavior, as druckermanly's answer correctly points out.

Some other answers (phinz's and Deuchie's) argue that the key must not be stored as a const object because the node handle resulted from extracting nodes out of the map allow non-const access to the key. This inference may seem plausible at first, but P0083R3, the paper that introduced the extract functionalities), has a dedicated section on this topic that invalidates this argument:

Concerns

Several concerns have been raised about this design. We will address them here.

Undefined behavior

The most difficult part of this proposal from a theoretical perspective is the fact that the extracted element retains its const key type. This prevents moving out of it or changing it. To solve this, we have provided the key accessor function, which provides non-const access to the key in the element held by the node handle. This function requires implementation "magic" to ensure that it works correctly in the presence of compiler optimizations. One way to do this is with a union of pair<const key_type, mapped_type> and pair<key_type, mapped_type>. The conversion between these can be effected safely using a technique similar to that used by std::launder on extraction and reinsertion.

We do not feel that this poses any technical or philosophical problem. One of the reasons the Standard Library exists is to write non-portable and magical code that the client can’t write in portable C++ (e.g. <atomic>, <typeinfo>, <type_traits>, etc.). This is just another such example. All that is required of compiler vendors to implement this magic is that they not exploit undefined behavior in unions for optimization purposes—and currently compilers already promise this (to the extent that it is being taken advantage of here).

This does impose a restriction on the client that, if these functions are used, std::pair cannot be specialized such that pair<const key_type, mapped_type> has a different layout than pair<key_type, mapped_type>. We feel the likelihood of anyone actually wanting to do this is effectively zero, and in the formal wording we restrict any specialization of these pairs.

Note that the key member function is the only place where such tricks are necessary, and that no changes to the containers or pair are required.

(emphasis mine)