Size: a a a

Конференция C++ Russia

2021 March 06

LA

Liber Azerate in Конференция C++ Russia
Собственно, если бы вызов был напрямую:
f(1), здесь 1 – тоже prvalue
источник

PZ

Pavel Zhigulin in Конференция C++ Russia
Liber Azerate
Я уже добрался до этого
Однако здесь больше подходит это:
https://eel.is/c++draft/conv.lval#3.4
И я всё ещё не понимаю
Я полагаю о том, что будет результатом конвертации надо начинать думать только после того, как мы объявили конвертацию возможной. А мы её таковой вроде не объявили, поэтому и результат не вычисляем.
источник

LA

Liber Azerate in Конференция C++ Russia
Pavel Zhigulin
Я полагаю о том, что будет результатом конвертации надо начинать думать только после того, как мы объявили конвертацию возможной. А мы её таковой вроде не объявили, поэтому и результат не вычисляем.
В смысле не объявили? Если бы у нас этой конвертации не было, у нас бы ни одна перегрузка вызваться не смогла бы. Здесь вызываются именно эти, потому что сначала идёт каст к првалью, а потом каст к флоату/инту. Который, между прочим, для првалью только и работает
источник

LA

Liber Azerate in Конференция C++ Russia
источник

PZ

Pavel Zhigulin in Конференция C++ Russia
А там случаем не это срабатывает?
https://en.cppreference.com/w/cpp/language/implicit_conversion#Temporary_materialization
источник

PZ

Pavel Zhigulin in Конференция C++ Russia
Хотя это из С++17...
источник

LA

Liber Azerate in Конференция C++ Russia
Ну да, это. Только как это объясняет происходящее?
источник

LA

Liber Azerate in Конференция C++ Russia
Pavel Zhigulin
Хотя это из С++17...
Там всё равно fold expression
источник

LA

Liber Azerate in Конференция C++ Russia
Что, как недавно выясняли ещё на С++ Сибирь, таки 17-ый стандарт :)
источник

PZ

Pavel Zhigulin in Конференция C++ Russia
Liber Azerate
Ну да, это. Только как это объясняет происходящее?
1. Вызываем g(float&&, int&&)
2. Пытаемся вызвать f(float&&). Провал (нужно r-value, а мы передаем l-value)
3. Ищем другую перегрузку
4. Находим, что можно замутить temporary materialization от float к int&&
5. Вызываем f(int&&) для аргумента float&&
источник

PZ

Pavel Zhigulin in Конференция C++ Russia
Liber Azerate
Там всё равно fold expression
Это можно переписать на С++11
источник

PZ

Pavel Zhigulin in Конференция C++ Russia
источник

LA

Liber Azerate in Конференция C++ Russia
Pavel Zhigulin
1. Вызываем g(float&&, int&&)
2. Пытаемся вызвать f(float&&). Провал (нужно r-value, а мы передаем l-value)
3. Ищем другую перегрузку
4. Находим, что можно замутить temporary materialization от float к int&&
5. Вызываем f(int&&) для аргумента float&&
Нет, temporary materialization к int&& идёт через два преобразования, к тому же, нет ни единой причины, чтобы после первого несоответствия перегрузка с float&& отпала, учитывая, что там нужно всего одно преобразование. Я об этом. Ну или нужны правила для разрешения перегрузки (которые, по-моему, сильно налажали в данном случае, если так)
источник

LA

Liber Azerate in Конференция C++ Russia
Как бы, если та перегрузка без преобразований отпала, то и эта должна была бы. А так, мы могли бы сравнить сколько преобразований надо для каждой, и о чудо! Для первой всего одно. Я не помню, конечно, наизусть все правила разрешения перегрузки, простите меня, но если она в данном случае работает не так... Ну, я всё ещё считаю это дырой в системе типов
источник

LA

Liber Azerate in Конференция C++ Russia
Pavel Zhigulin
Это можно переписать на С++11
Да, то есть мы разобрались даже, что здесь не temporary materialization
источник

PZ

Pavel Zhigulin in Конференция C++ Russia
Ну, то что его не было в стандарте, не значит, что оно не работало))) Этот код отлично компилируется в С++11

```
#include <iostream>

using namespace std;

int main() {
   int a = '0';
   char const &b = a;
   cout << b;
   a++;
   cout << b;
}
```

И оно дважды выводит "0", а не "0" и "1".
источник

LA

Liber Azerate in Конференция C++ Russia
Pavel Zhigulin
Ну, то что его не было в стандарте, не значит, что оно не работало))) Этот код отлично компилируется в С++11

```
#include <iostream>

using namespace std;

int main() {
   int a = '0';
   char const &b = a;
   cout << b;
   a++;
   cout << b;
}
```

И оно дважды выводит "0", а не "0" и "1".
Меня это не удивляет, здесь всё логично. Если бы оно работало иначе, здесь были бы проблемы посерьёзнее, чем с системой типов, наверно. Впрочем, это сродни сломанным structured binding'ам
источник

PZ

Pavel Zhigulin in Конференция C++ Russia
Liber Azerate
Как бы, если та перегрузка без преобразований отпала, то и эта должна была бы. А так, мы могли бы сравнить сколько преобразований надо для каждой, и о чудо! Для первой всего одно. Я не помню, конечно, наизусть все правила разрешения перегрузки, простите меня, но если она в данном случае работает не так... Ну, я всё ещё считаю это дырой в системе типов
Мне нужно еще несколько минут, чтобы подумать почему не срабатывает lvalue-to-rvalue conversion.
источник

V

Vlad in Конференция C++ Russia
А че не так с "MIN_INT / -1"?
источник

PZ

Pavel Zhigulin in Конференция C++ Russia
Просто  если закомментировать одну из функций "f" будет ошибка компиляции. Что говорит о том, что lvalue float&& нельзя скастить в rvalue float&& )
источник