Здравствуйте, Николай Ивченков, Вы писали:
НИ>Тогда я не понимаю, в чём заключается суть твоего возражения с упоминанием значений.
НИ>Если P — это не T &, то что тогда?
Поетнциально здесь возможны два варианта: квалификатор удаляется при выводе типов, либо уже удален к этому времени. Первоначально я склонялся ко второму варианту. Попытка притянуть за уши 'function template parameter' не выдерживает критики, здесь ты прав.
Собственно остается только вероятность наличия второго варианта, т.к. об удалении квалификаторов с non-class rvalues при выводе типов ничего не сказано. Но с одной стороны — тип выражения однозначно завсит от его вида, с другой — не во всех контекстах эта зависимость используется. Хотя например в 5.4/1, 5.2.3/2 очень похожая ситуация: явно определяется тип выражения (T), но рядом находится примечание:
Note: if T is a non-class type that is cv-qualified, the cv-qualifiers are ignored when determining the type of the resulting rvalue (3.10).
Здравствуйте, Николай Ивченков, Вы писали:
НИ>Формулировка "function template parameter type (call it P)", на мой взгляд, выбрана неудачно
. . . НИ>P — не что иное, как type of function parameter of function template.
"type of function parameter of function template" — это корректный английский?
Юрий Жмеренецкий:
ЮЖ>Хотя например в 5.4/1, 5.2.3/2 очень похожая ситуация: явно определяется тип выражения (T), но рядом находится примечание:
ЮЖ>
Note: if T is a non-class type that is cv-qualified, the cv-qualifiers are ignored when determining the type of the resulting rvalue (3.10).
Здесь та же проблема. Примечания не являются нормативными.
Сравни две формулировки:
1) "non-class rvalues always have cv-unqualified types." (то, что есть)
2) "If an rvalue initially has the cv-qualified type "cv T", where T is non-class type, the type of the rvalue is adjusted to "T" prior to any further analysis." (то, что могло бы быть)
Как видно, не все разработчики компиляторов имеют достаточно телепатических способностей, чтобы трактовать первую формулировку, как вторую.
Здравствуйте, Николай Ивченков, Вы писали:
ЮЖ>>Хотя например в 5.4/1, 5.2.3/2 очень похожая ситуация: явно определяется тип выражения (T), но рядом находится примечание:
ЮЖ>>
Note: if T is a non-class type that is cv-qualified, the cv-qualifiers are ignored when determining the type of the resulting rvalue (3.10).
НИ>Здесь та же проблема. Примечания не являются нормативными.
Разумеется. Но выше тип определяется как 'T', а не как 'type of the resulting rvalue' (притянуто) .
НИ>Сравни две формулировки:
НИ>1) "non-class rvalues always have cv-unqualified types." (то, что есть) НИ>2) "If an rvalue initially has the cv-qualified type "cv T", where T is non-class type, the type of the rvalue is adjusted to "T" prior to any further analysis." (то, что могло бы быть)
Хм.. И как бы это изменило ситуацию? При выводе типов используется тип аргумента, который эквивалентен типу выражения, а это в свою очередь — "return type of the statically chosen function". Тот факт, что при определении типа resulting rvalue мы получим 'int', проскальзывает мимо.
Юрий Жмеренецкий:
ЮЖ>Но выше тип определяется как 'T', а не как 'type of the resulting rvalue' (притянуто) .
Я не понял твою мысль.
НИ>>Сравни две формулировки:
НИ>>1) "non-class rvalues always have cv-unqualified types." (то, что есть) НИ>>2) "If an rvalue initially has the cv-qualified type "cv T", where T is non-class type, the type of the rvalue is adjusted to "T" prior to any further analysis." (то, что могло бы быть)
ЮЖ>Хм.. И как бы это изменило ситуацию?
Точно так же, как и в случае со ссылками:
int &f();
template <class T>
char g(T);
int main()
{
sizeof g(f());
}
Согласно тому же 5.2.2/3 здесь изначальным типом выражения f() является "int &". Далее вступает в силу 5/6:
If an expression initially has the type “reference to T” (8.3.2, 8.5.3), the type is adjusted to “T” prior to any further analysis, the expression designates the object or function denoted by the reference, and the expression is an lvalue.
— таким образом, тип выражения f() корректируется до "int".
ЮЖ>При выводе типов используется тип аргумента, который эквивалентен типу выражения, а это в свою очередь — "return type of the statically chosen function".
"return type of the statically chosen function" относится к начальному типу выражения, который может быть скорректирован. В процессе дедукции за A берётся скорректированный тип. В примере выше это будет "int", а не "int &".
Здравствуйте, Николай Ивченков, Вы писали:
ЮЖ>>Но выше тип определяется как 'T', а не как 'type of the resulting rvalue' (притянуто) .
НИ>Я не понял твою мысль.
У меня есть подозрение, что те компиляторы, которые выводят тип как const int, не учитывают тот факт, что аргументом является rvalue (и поэтому не снимают квалификатор) и используют "return type of the statically chosen function". Поэтому та формулировка, которую ты привел, не может повлиять на это.
НИ>>>1) "non-class rvalues always have cv-unqualified types." (то, что есть) НИ>>>2) "If an rvalue initially has the cv-qualified type "cv T", where T is non-class type, the type of the rvalue is adjusted to "T" prior to any further analysis." (то, что могло бы быть)
ЮЖ>>Хм.. И как бы это изменило ситуацию?
НИ>Точно так же, как и в случае со ссылками:
<...>
НИ>- таким образом, тип выражения f() корректируется до "int".
И все-таки я не понимаю, чем тебе не нравится 3.10/5:
The result of calling a function that does not return a reference is an rvalue.
В совокупности в "non-class rvalues always have cv-unqualified types." ?
ЮЖ>>При выводе типов используется тип аргумента, который эквивалентен типу выражения, а это в свою очередь — "return type of the statically chosen function".
НИ>"return type of the statically chosen function" относится к начальному типу выражения, который может быть скорректирован. В процессе дедукции за A берётся скорректированный тип.
Тогда в чем выражаются претензии? Ведь изначально ты ссылался на то, что о снятии квалификатора ничего не сказано.
Юрий Жмеренецкий:
ЮЖ>У меня есть подозрение, что те компиляторы, которые выводят тип как const int, не учитывают тот факт, что аргументом является rvalue (и поэтому не снимают квалификатор) и используют "return type of the statically chosen function". Поэтому та формулировка, которую ты привел, не может повлиять на это.
Type deduction относилось бы к "any further analysis", поэтому компилятор был бы просто обязан учесть тот факт, что аргумент — rvalue, чтобы окончательно установить его тип.
НИ>>"return type of the statically chosen function" относится к начальному типу выражения, который может быть скорректирован. В процессе дедукции за A берётся скорректированный тип.
ЮЖ>Тогда в чем выражаются претензии?
В нормативном тексте стандарта нет формулировки о снятии cv-квалификатора с non-class rvalue. Если лишь утверждение, из которого следует, что cv-квалифицированных non-class rvalues не бывает. В то же время формулировки
"The type of the function call expression is the return type of the statically chosen function" (5.2.2/3) и
"A function call is an lvalue if and only if the result type is a reference." (5.2.2/10)
"Every expression is either an lvalue or an rvalue." (3.10/1)
подразумевают, что образование cv-квалифицированного non-class rvalue возможно. Каким образом разрешается такой парадокс, остаётся только гадать. Для документа, претендующего на название международного стандарта, такая ситуация выглядит просто дико.
В идеале точный тип выражения вообще следовало бы определять сразу в одном подпункте (будь то 5.2.2, 5.2.3 или 5.4), а не посредством корректировок, за которыми нужно лезть в совсем другой раздел стандарта.