0
#include <iostream>
#include <map>

using namespace std;

int main()
{
    int number = 10;
    map<int*, int> intmap;
    intmap.insert(pair<int*, int>(&number, 1));
    
    for (auto const &  x : intmap)
    {
        (*x.first)++;
        
    }

    for (auto const &  x : intmap)
    {
        cout << (*x.first) << "::" << x.second; //prints 11::1
    }
    return 0;
}

In this answer its mentioned that

Choose auto const &x when you want to work with original items and will not modify them.

but in the above program, I am able to modify it. Looks like the x in for loop is constant pointer rather than a pointer to constant.

samnaction
  • 1,194
  • 1
  • 17
  • 45

2 Answers2

3

You are not modifying map or map elements. You are modifying pointee, and there's nothing to prevent you from doing that (apart from changing map type).

The type of x is const std::pair<int* const, int>&, or a reference to const pair. Notice that the first element of the pair is a constant pointer, but it is not pointing to a constant value.
With this, you are not allowed to modify either pair elements (x.first++ and x.second++ would both fail).
However, since x.first is a const pointer to non-const int, *x.first is just a regular int&, no const here, and you can increment it.

If you want to prevent such situation, you can change map key type to const int*, aka. pointer to const int.

map<const int*, int> intmap;

Also note that you cannot modify key (or the first value in pair) even with non-const reference:

for (auto &  x : intmap)
{
    x.first++; //fails
}
Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • Understood, but for map the for loop pair is then for the pointer key value shouldn't it to be const*int rather that int * const ? – samnaction Dec 27 '20 at 15:54
  • @samnactionThe key (the pointer) is what's const so `int * const` is correct. If the pointed-to object was const it would be `const int *`. The placement of `const` before or after the asterisk is important. – Blastfurnace Dec 27 '20 at 15:59
  • @Yksisarvinen Erm, `int*` most certainly converts to `const int*`. Did you mean to say "adding `const` to `int*` gives `int *const` and not `int const*`"? This is why (IMO) `const` should always be written *after* the type... (and that way it also comes at the correct position in the reading order) – HTNW Dec 27 '20 at 21:49
0

Similar case:

int x = 0;
int* const p = &x;
*p = 42;

A constant pointer cannot be modified, but you can use it to modify what it points to. Only a const int*, pointer to constant int, would prevent that.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185