When auto is used against array, why it's converted to pointer and not reference? When auto is used against array, why it's converted to pointer and not reference? arrays arrays

When auto is used against array, why it's converted to pointer and not reference?


Yes. In that expression, the array decays into pointer type, due to lvalue-to-rvalue conversion.

If you want array type , not pointer type, then do this:

auto & x = arr; //now it doesn't decay into pointer type!

& in the target type prevents the array from decaying into pointer type!


x is an array and not a pointer, can be proved as:

void f(int (&a)[10]) {    std::cout << "f() is called. that means, x is an array!" << std::endl;}int main() {     int arr[10];     auto & x = arr;      f(x); //okay iff x is an int array of size 10, else compilation error!}

Output:

f() is called. that means, x is an array!

Demo at ideone : http://www.ideone.com/L2Ifp

Note that f cannot be called with pointer type. It can be called with an int array of size 10. Attempting to call it with any other type, will result in compilation error.


auto produces values. It will not produce references. With this in mind, then the pointer is the trivial conversion to a value that the array offers.


To provide a standard reference for the behavior, 7.1.6.4 [dcl.spec.auto] paragraph 6 reads:

Once the type of a declarator-id has been determined according to 8.3, the type of the declared variable using the declarator-id is determined from the type of its initializer using the rules for template argument deduction. Let T be the type that has been determined for a variable identifier d. Obtain P from T by replacing the occurrences of auto with ... a new invented type template parameter U ... The type deduced for the variable d is then the deduced A determined using the rules of template argument deduction from a function call (14.8.2.1), where P is a function template parameter type and the initializer for d is the corresponding argument. If the deduction fails, the declaration is ill-formed.

So we need to look elsewhere, specifically 14.8.2.1 [tmp.deduct.call] paragraph 2:

If P is not a reference type: — If A is an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is used in place of A for type deduction

For completeness sake, 4.2 [conv.array] paragraph 1:

An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.

To step through it, auto x = arr; creates an imaginary function template<typename P> f(P); and attempts to deduce P from the call f(arr). A in this case is array of 10 int, and P is not a reference type, so A becomes pointer to int instead. Which percolates up the chain back into the final type of x.

So basically, it is treated as a pointer because the rules say it must. The behavior is simply more useful this way, since arrays are not assignable. Otherwise, your auto x = arr; would fail to compile rather than do something useful.