'How to get on top-level const pointer using "auto"?

In short words:

Per C++ Primer, pg 69, "auto": "If we want the deduced type to have a top-level const, we must say so explicitly".

I would get an top-level const pointer:

int i = 42;
const auto *p = &i;

But the resulted p has type const int * instead of expected int * const. I can even reassign it p = 0;. why? (note: the format of pointer type deduction using auto * is from the book.)



Solution 1:[1]

In your example, p is a pointer to a const int, not a const pointer to an int. The latter can be achieved with the following statement:

auto* const p = &i;

Solution 2:[2]

With auto, you don't even need the asterisk, which makes it easy:

const auto p = &i;

Here, auto deduces the type to be int *, making it int * const. Note that whether it's const auto or auto const does not make a difference, just as with a typedef name.

In your example, only int fits as the deduced type, making p a const int *. This is not a top-level const, but a pointer to a const int.

See it work here.

Solution 3:[3]

Considering your original code,

int i = 42;
const auto *p = &i;

adding a

cout << typeid(p).name() << endl;

reports

int const *

with Visual C++.

Which contradicts your statement

the resulted p has type int *


Here's one way to take full control:

int i = 42;
auto const *const p = &i;

Remove the first const if you want a const pointer to mutable object.


Alternatively, as noted by chris in his answer, if you want a const pointer to mutable object you can just do

auto const p = &i;

Solution 4:[4]

The type deduction through auto works exactly as it does for function templates. So, when you write const auto *p = &i;, the type of p is exactly the type of p in the call to the below template which would match f(&i).

template<typename U>
void f(const U* p);

Thus, the type is const int*. If you want p to be int * const, the right expression is auto * const p = &i.

Solution 5:[5]

Position of const before/after the pointer declaration(*) changes the meaning.

Below example shows a few combination of with auto, const and * - and their interpretation.

    int main() {
        auto i = 2;               // int

        const auto a = &i;        // int * const
        // a = &j;                // Error: addr is const
        *a = 4;                   // OK (value is NOT const)

        const auto* b = &i;       // const int *
        // *b = 4;                // Error: value is const
        b = &j;                   // OK (addr is NOT const)

        auto* const c = &i;       // const int *       - (Your case!)
        *c = 4;                   // OK (value is NOT const)
        // c = &j;                // Error: addr is const

        const auto* const d = &i; // const int * const
        // *d = 4;                // Error: Both value & addr are const
        // d = &j;                // Error: Both value & addr are const
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 nosid
Solution 2
Solution 3 Community
Solution 4 Pradhan
Solution 5 SridharKritha