Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
0 / 0 / 0
Регистрация: 18.08.2017
Сообщений: 1
1

Конвертация между rvalue и lvalue при передаче аргумента в функцию

18.08.2017, 22:45. Показов 2777. Ответов 15
Метки 1, c, c++11, rvalue, c++ (Все метки)

Author24 — интернет-сервис помощи студентам
Как это конвертируется если я обявил аргумент типа lvalue а передаю обьект rvalue ?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>
 
using namespace std;
 
void f(vector<int>& a) {
    a[0] = 7;
}
 
 
int main() {
 
    vector<int>&& a = { 5 };
 
    f(a);
    cout << a[0] << endl;
 
    for (;;);
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.08.2017, 22:45
Ответы с готовыми решениями:

C++ expressions - rvalue, glvalue, prvalue, xvalue, lvalue, а также rvalue reference: что есть что?
Доброго времени суток, не понимаю до конца деление С++ - выражений (приложение 1). Lvalue вроде...

Lvalue и rvalue
Какая выгода использования rvalue? Допустим есть такой класс class A { public: A() =...

Значения Lvalue и Rvalue
Здравствуйте. В данной ссылке https://msdn.microsoft.com/ru-ru/library/f90831hc.aspx приведен...

Rvalue и lvalue ссылки
Здравствуйте, что расскажите, пожалуйста что такое lvalue и rvalue ссылки и с чем их едят, где...

15
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
19.08.2017, 01:54 2
Цитата Сообщение от david_tsaturyan Посмотреть сообщение
а передаю обьект rvalue ?
Вы путаете rvalue и rvalue-reference.
0
18 / 17 / 16
Регистрация: 04.07.2017
Сообщений: 36
19.08.2017, 02:25 3
Цитата Сообщение от david_tsaturyan Посмотреть сообщение
я обявил аргумент типа lvalue а передаю обьект rvalue
на самом деле это rvalue-reference(rvalue – все, у чего нету имени).
После объявления такие переменные – одно и то же:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MyClass
{
    string name;
public:
    MyClass(const char* value){ name = value; cout << "constructed " << name << endl; }
    MyClass(MyClass&& r) { name = r.name; cout << "moved " << name << endl; }
    MyClass(const MyClass& r) {  cout << "copied " << r.name << endl; name = "copy of " + r.name;}
    ~MyClass(){ cout << "destructed " << name << endl; }
};
int main()
{
    MyClass s1 = MyClass("s1");// неявный конструктор
    MyClass& s2 = MyClass("s2");// присвоение адреса
    MyClass&& s3 = MyClass("s3");// присвоение адреса, но только от rvalue
                                 // для фундаментальных типов будет неявная переменная-посредник
    MyClass ss1 = s1;
    MyClass ss2 = s2;
    MyClass ss3 = s3;
}
Rvalue существует только для того, чтобы можно было написать конструктор, который принимает временные объекты, чтобы можно было присвоить значения указателей, а не выделять заново память и копировать в нее с конструктором копирования.
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
19.08.2017, 02:42 4
Цитата Сообщение от Quaentor Посмотреть сообщение
C++
1
MyClass s1 = MyClass("s1");// неявный конструктор
Почему неявный?
1
Любитель чаепитий
3742 / 1798 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
19.08.2017, 10:25 5
Цитата Сообщение от Quaentor Посмотреть сообщение
MyClass& s2 = MyClass("s2");// присвоение адреса
НЕ-константная ссылка не может принять rvalue.
1
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
19.08.2017, 10:54 6
GbaLog-,
Уверены?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//g++  5.4.0
 
#include <iostream>
 
struct Foo
{
    int n = 0;
    int& get()
    {
       return n;
    }
    
};
 
void test(int& n)
{
    std::cout << n;
}
 
int main()
{
    Foo f;
    f.n = 100;
    test(f.get());
}
http://rextester.com/NUYK68866

Добавлено через 7 минут
f.get() тут разве не rvalue?
0
Любитель чаепитий
3742 / 1798 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
19.08.2017, 11:51 7
Цитата Сообщение от Undisputed Посмотреть сообщение
f.get() тут разве не rvalue?
нет.
это lvalue-reference.
просто число передайте в test и компилятор выдаст ошибку компиляции.
или у get уберите амперсанд.
0
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
19.08.2017, 12:44 8
GbaLog-,
Так rvalue же это свойство выражений а не данных(это я к тому, что от того что я уберу ссылку в возвращаемом типе само выражение вызывающее функцию не изменится)
0
18 / 17 / 16
Регистрация: 04.07.2017
Сообщений: 36
19.08.2017, 13:10 9
Цитата Сообщение от nd2 Посмотреть сообщение
Почему неявный?
Ошибся, перепутал с MyClass my = "my";
Цитата Сообщение от GbaLog- Посмотреть сообщение
НЕ-константная ссылка не может принять rvalue.
Да, верно. Но все же VС++ позволяет делать подобное(а почему бы и нет?).
И при этом можно rvalue reference присвоить к lvalue reference: http://rextester.com/edit/AAWNQD10555
C++
1
2
    string&& rref = string();
    string& lref = rref;
К чему тогда эта стена – не понимаю. Хотя в конечном итоге это не особо важно.
0
Любитель чаепитий
3742 / 1798 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
19.08.2017, 16:02 10
Цитата Сообщение от Undisputed Посмотреть сообщение
это я к тому, что от того что я уберу ссылку в возвращаемом типе само выражение вызывающее функцию не изменится
ещё как изменится, раньше было test(int&);, что подходило под сигнатуру функции целиком и полностью.
потом станет test(int);, но при этом test не способна принять временный объект, а возвращаемый из get объект временный.
вызывающий код не изменится, но вот контекст поменяется, на что и среагирует компилятор.
1
17 / 16 / 3
Регистрация: 18.08.2017
Сообщений: 54
19.08.2017, 16:52 11
Цитата Сообщение от Undisputed Посмотреть сообщение
f.get() тут разве не rvalue?
Тип возвращаемого значения у функции lvalue-ссылка, значит выражение, состоящее из вызова этой функции, является lvalue.

Цитата Сообщение от GbaLog- Посмотреть сообщение
Цитата Сообщение от Undisputed Посмотреть сообщение
f.get() тут разве не rvalue?
нет.
это lvalue-reference.
Вы перепутали lvalue-reference с lvalue.

Цитата Сообщение от Undisputed Посмотреть сообщение
от того что я уберу ссылку в возвращаемом типе само выражение вызывающее функцию не изменится
Изменится его категория. С lvalue на prvalue.
1
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
19.08.2017, 16:52 12
Цитата Сообщение от Quaentor Посмотреть сообщение
Да, верно. Но все же VС++ позволяет делать подобное(а почему бы и нет?).
И при этом можно rvalue reference присвоить к lvalue reference:
C++
1
2
string&& rref = string();
string& lref = rref;
Цитата Сообщение от Quaentor Посмотреть сообщение
К чему тогда эта стена – не понимаю.
так одно дело, когда вы сами пишите явный код преобразований.
и другое - что компилятор не станет делать подобных преобразований неявно

с чем может быть связан запрет?
на самом деле вопрос интересный)
я подозреваю, что это как то связанно
с "историческим" наследием раздолбайства непродуманного дизайна
языка си.

но что характерно, даже вижуал студия,
с её "нестандартным расширением от компилятора"
отказалась компилить такой код:

http://rextester.com/OHZB45178

C++
1
2
3
4
5
6
7
8
9
int foo() { return 10; }
 
int main()
{
    int& ref = foo();  //<--- дыра в безопасности
 
    // теперь мы можем модифицировать константу
    ref = 100;   
}
проблема дизайна языка си в том,
что литерные числовые константы - это константы
нельзя модифицировать их значения.

однако временный объект константным не является.

в действительности, если бы это был объект класса,
то можно было бы вполне законно
вызывать любые его не-константные функции-члены.

и вот здесь частоколом возникают перпендикулярные проблемы дизайна:
так временный объект, он константный или нет?
и если он - константа, тогда какого фига
он не наделен квалификатором const ?

или вот такой вопросик:
если числовые литерные константы - это константы,
тогда что именно мы модифицировали в этом коде?

C++
1
2
3
4
5
6
int foo() { return 10; }
int main()
{
    int&& ref = foo();
    ref = 100;
}
0
18 / 17 / 16
Регистрация: 04.07.2017
Сообщений: 36
19.08.2017, 18:30 13
Цитата Сообщение от hoggy Посмотреть сообщение
или вот такой вопросик:
если числовые литерные константы - это константы,
тогда что именно мы модифицировали в этом коде?
неявную переменную-посредник

Цитата Сообщение от hoggy Посмотреть сообщение
но что характерно, даже вижуал студия,
с её "нестандартным расширением от компилятора"
отказалась компилить такой код:
это да, странно. Эдакое исключение, просто "потому что"

Цитата Сообщение от hoggy Посмотреть сообщение
так временный объект, он константный или нет?
и если он - константа, тогда какого фига
он не наделен квалификатором const ?
а чего ему быть константным? Const же для имен, чтобы не начудить.
Цитата Сообщение от hoggy Посмотреть сообщение
проблема дизайна языка си в том,
что литерные числовые константы - это константы
нельзя модифицировать их значения.
опять же, как они могут быть константами
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
19.08.2017, 19:01 14
Цитата Сообщение от Quaentor Посмотреть сообщение
неявную переменную-посредник
с какой стати?

что вы вообще хотите этим сказать?

что rvalue-reference ссылается не на временный объект,
который вернула функция, а на его копию?

то бишь у нас на самом деле два временных объекта.

что за бред?

Цитата Сообщение от Quaentor Посмотреть сообщение
а чего ему быть константным? Const же для имен, чтобы не начудить.
язык различает константные объекты (рожденные константными),
и все прочие объекты.

стандарт говорит:
модификация объекта, константного от рождения - UB

вообще то, компилятор может и не выделять память под числовые константы,
а тупо инлайном подставлять значение по месту использования.

однако, литерная числовая константа - полноценный объект.
а значит, мы вполне легально можем попросить его адрес:

C++
1
2
const int& ref = 10;
const int* ptr = &ref;
и здесь компилятору ничего не остается,
кроме как честно расположить объект в памяти.
что бы можно было вернуть его адрес.

однако, компилятор видит - что объект "константа от рождения",
и может запросто расположить его в памяти "только для чтения".

если в последствии мы применим const_cast,
и сняв с объекта константность,
попробуем модифицировать его,
то запросто можем нарваться на "акццесс виолейшен",
например.


в кратце: компилятор видя, что объект - константа от рождения,
закладывается на его неизменчивость,
что открывает ему пути для возможных оптимизаций.


Цитата Сообщение от Quaentor Посмотреть сообщение
опять же, как они могут быть константами
как литерная числовая константа может быть константой?
вы вообще понимаете о чем спрашиваете?

литерные числовые константы - не просто константы.
это - константы времени компиляции.
0
18 / 17 / 16
Регистрация: 04.07.2017
Сообщений: 36
19.08.2017, 19:34 15
hoggy, извини, но дальнейшее обсуждение бесполезно. Ты видишь так, я вижу так.
И уж тем более, письменный-то спор будет просто трепкой нервов
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
19.08.2017, 19:45 16
Цитата Сообщение от Quaentor Посмотреть сообщение
дальнейшее обсуждение бесполезно. Ты видишь так, я вижу так.
бесполезно обсуждать что либо с водителем,
который руководствуется собственным виденьем,
а не ПДД.
0
19.08.2017, 19:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.08.2017, 19:45
Помогаю со студенческими работами здесь

Почему i++ это rvalue, а ++i lvalue?
Встречал упоминания что для постинкремента создается временная копия, но дальше не объясняется....

Что такое rvalue и lvalue
как понимать эти штуки?

Непонятное поведение rvalue/lvalue
Всем привет, объясните, пожалуйста, немного про р-вэлью и л-вэлью в этом коде: #include &lt;iostream&gt;...

Семантика перемещения rvalue\lvalue ссылок
Здравствуйте форумчани. Объясните пожалуйста процессы происходящии внутрии функции swap принимающую...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru