Why can I pass the key of std::map to a function that expects non-const?

Viewed 323

According to std::map documentation, it stores the key-value pairs in std::pair<const Key, Value>, so the keys in the map are const.

Now imagine that I have an std::map where the keys are the pointers to some objects.

struct S {};
struct Data {};
using MyMap = std::map<S*, Data>;

Let's also assume there is a function foo that accepts S* parameter.

void foo(S* ptr) { /* modify the object (*ptr) */ }

Now, the question is: when I iterate over MyMap with range-based for-loop, I am able to pass the map element key to foo:

MyMap m = getMyMapSomehow();
for (auto elem : m)
{
    static_assert(std::is_const<decltype(elem.first)>::value, "Supposed to be `const S*`");
    foo(elem.first); // why does it compile?
}

So, even though my static_assert succeeds (so I assume that the type of elem.first is const S*), the call to foo compiles fine, and therefore it look as if I'm able to modify the object behind pointer-to-const.

Why am I able to do that?

P.S. Here's a live example at Coliru that illustrates my point. For brevity, I use int instead of S and Data.

3 Answers
Related