Ответ 1
Я думаю, это зависит от того, что означает определенная фраза.
Оба преобразования эквивалентны, потому что мы исключаем lvalue transformations (в основном массив эффективно является указателем, поэтому он не считается преобразованием), поэтому мы попадаем в следующий тай-брейк, который вы указали в [over.ics.rank]:
S1 и S2 являются привязками привязок, и ни один из них не ссылается на неявный объектный параметр нестатической функции-члена, объявленной без ref-квалификатора, а S1 связывает ссылку rvalue с rvalue и S2 связывается ссылка lvalue
Используется ли этот случай? У нас есть две привязки привязки:
int arr[6];
int (&a)[6] = arr; // #1
int *&& b = arr; // #2
Здесь # 1 связывает ссылку lvalue. # 2 попадает в [dcl.init.ref]:
В противном случае выражение инициализатора неявно преобразуется в prvalue типа "cv1 T1". Временное преобразование материализации применяется, и ссылка привязана к результату.
arr
неявно преобразуется в prvalue типа int*
, который затем привязан к b
.
Итак, теперь вопрос в том, что означает ограничение в [over.ics.rank]? Это может означать:
- ссылка rvalue, которая, как правило, связана с r значением. Это, по-видимому, толкование. Ссылка rvalue привязана к временному материализованному из преобразования prvalue
arr
. - в частности, выражение аргумента представляет собой rvalue, связанное с параметром ссылки rvalue. Это, по-видимому, gcc-интерпретация, и поскольку
arr
не является rvalue (это значение lvalue), этот тай-брейк пропущен и не применяются последующие тай-брейки.
Я склонен поддержать реализацию gcc здесь. В противном случае, как бы фраза "связывает ссылку rvalue с rvalue"? Ссылки Rvalue не могут связываться с lvalues. Это избыточно. Тем не менее, он неловко сформулировал эту интерпретацию.
Как есть, я назову это ошибкой формулировки.