List all the situations when an array is not conve

2020-02-11 08:49发布

问题:

So far I have encountered 3 situations where array stays as an array: (assume int arr[3][4];)

  1. sizeof(arr) : gives the total size (not one element's)
  2. &arr + 1: advances the address by total size
  3. binding a reference to interior array in range for:

//

   for(const auto &row : arr)
       for(auto col : row)
           cout << col << endl;

Question: Does this exhaust all the situations where array is not converted to a pointer to a single element? If not, is there a systematic way of deciding it?

回答1:

Most of the cases where this conversion happens are covered by [expr]#8:

Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue (4.1), array-to-pointer (4.2), or function-to-pointer (4.3) standard conversions are applied to convert the expression to a prvalue.

All of the operators which can take arr expect a prvalue (or otherwise explicitly request this conversion), except for:

  • unary &
  • sizeof
  • ++
  • --
  • alignof
  • typeid

(Note: this list might not be exhaustive, I will update it if someone points out other cases!)

Now, There are various possible cases where we can use arr and it is not the operand of any operator. Some of those cases perform the conversion and some don't. The ones that do perform the conversion are:

  • using arr as a function argument but not matching a prototype parameter
  • some cases of template type deduction
  • deducing the return type of a lambda

Notably, the conversion is not performed by binding arr to a reference (this is what happens in the range-based for-loop). This is covered by [dcl.init.ref]#5. In the line T &ref = arr;, the = is not the assignment operator; it's part of the syntax for declarations.