Usage of auto in C++11

When I use auto to deduce a pointer type, I found a weird phenomenon. My code is like this:

#include <iostream>
using namespace std;
int main()
{
    int i = 100;
    auto p1 = &i;
    auto *p2 = &i;

    cout << *p1 << " " << *p2 << endl;

    return 0;
}

After compiling and executing, we can find that the result of *p1 and *p2 is the same, both 100. This means p1 and p2 are both a pointer object which points to an int object.

[user@host ~]$ ./test 
100 100

Is there any difference between these two statements which define p1 and p2?


The difference is that in the first case auto is deduced to int* while in the second case auto is deduced to int, which results in both p1 and p2 being of type int*. The type deduction mechanism for auto is equivalent to that of template arguments. The type deduction in your example is therefore similar to

template<typename T>
void foo(T p1);

template<typename T>
void bar(T* p2);

int main()
{
    int i;
    foo(&i);
    bar(&i);
}

where both functions are instantiated as type void(int*) but in the first case T is deduced to int* while in the second case T has type int.


auto specifier used in declarations of variables, deduces its type with the same rules as used in template argument deduction.

Consider your first example (i.e., auto p1 = &i;). The type of auto specifier is deduced as follows:

  1. auto is replaced with an imaginary type template parameter (e.g., U p1 = &i;).
  2. &i type is int*, thus with no surprises and according to template deduction rules U is deduced to int*.

Now consider your second example (i.e., auto *p2 = &i).

  1. Again auto is replaced with an imaginary type template parameter (e.g., U* p1 = &i;).
  2. &i type is int*, thus according to template deduction rules U is deduced to int.

As such, in auto *p2 = &i; the placeholder type auto will correctly be deduced as int and not as int*, that would result in p2 being of type int**, as you might have expected.