2016-04-11 2 views
2

Я новичок в C++, и это мой первый вопрос здесь, так что несите со мной, пожалуйста ... Я читал о lvalue и rvalue некоторое время, и я думаю, что я понимаю большую часть этого, но есть немного, что все еще смущает меня ... так что мой вопрос будет конкретнымВ чем разница между ссылкой rvalue и значением xvalue?

ссылка RValue считается именующими (эта частью я понимаю), но функция, которые возвращают RValue ссылки считается RValue (или xvalue быть конкретным), например:

int x = 32; 
int& Lref = x; // Lref is lvalue ... ok 
int& funcA(); // calling funcA() is lvalue ... ok 

int&& Rref = 32; // Rref is lvalue ... ok I got this 
int&& funcB(); // calling funcB() is rvalue ... Why? 

Поэтому возникает вопрос: почему вызов funcB(), возвращающий ссылку rvalue, считается rvalue?

Заранее спасибо.

+0

'rvalue ссылки считаются lvalue', они иначе не имели бы 2 разных типа. –

+0

' Lref' является ссылкой на lvalue, но '32' нет, и он не будет компилироваться. Вам понадобится 'const &' или '&&', как вы также покажете. – edmz

+0

@ black Да, я ошибся, и я просто исправил это. – Laith

ответ

3

Чтобы ответить на титульной вопрос, «ссылка Rvalue» является своего рода типа, в то время как «xvalue» является своего рода выражением.

ссылки RValue считаются именующее (эта часть я понимаю)

Они не являются. Ссылки Rvalue являются типами, типы не являются выражениями и поэтому не могут быть «считаны lvalue». Вы имеете в виду, что если выражение состоит исключительно из имени переменной типа T&&, то это выражение lvalue типа T.

почему вызов funcB(), которые возвращают RValue ссылки считается Rvalue

Самым простым ответом был бы "по определению". Выражение вызова функции, где тип возвращаемого значения функции: T&&, представляет собой выражение xvalue типа T. Что касается мотивации, это именно то, что делает std::move делать то, что он делает: imbue любое выражение с возможностью перемещения из (также называемое «категория rvalue» - см. http://en.cppreference.com/w/cpp/language/value_category).

+0

Я признаю, что темы lvalue, rvalue и типа дедукции очень сбивают с толку ... плюс большинство сайтов просто не объясняют их ясным образом ... единственный способ, который помог мне понять их, - это посмотреть видео с самого Скотта Мейерса, объясняющего их ... теперь я лучше понимаю ... и спасибо за ваш ответ – Laith

+0

@WLION Я думаю, что он делает это более сложным, чем это. – Cubbi

1

Как правило, «объект», возвращаемый функцией, создается в части стека, связанной с самой функцией. То есть, возвращаемое значение должно быть скопировано (или перемещено) на новый объект, и этот объект является rvalue.

В вашем коде вы сделали ошибку для lref. 32 является ссылкой на rvalue.

Чтобы быть простым, ссылка на lvalue является объектом, с помощью которого мы можем получить адрес. Мы не можем получить адрес ссылки rvalue.

int a = 50; 
int &b = a; // Ok because we can get the address of a 
int &c = 50; // Error we can't get the address of 50 
int &&d = 50; // It is ok 

И он также работает с «объектом».

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

std::unique_ptr<int> foo() { 
    auto ptr = std::make_unique<int>(5); 
    return ptr; 
} 
auto a = foo(); // is correct, the ptr will be moved because it is a rvalue 

Эта функция должна возвращать правильное значение r. (Обычно компилятор, если вы не укажете, будет ли оно lvalue или rvalue использовать ссылку rvalue).

Может быть, вы могли бы взглянуть на: http://en.cppreference.com/w/cpp/language/value_category

Если неясно, дайте мне знать

+0

Да, я ошибся, и я просто исправил его, но ... «Мы не можем получить адрес ссылки rvalue» ... Я просто получил адрес & Rref, так что это не имеет смысла. – Laith

+0

Возможно, я не очень хорошо объяснил. Это не потому, что вы указали переменную как ссылку на rvalue, из которой вы не можете получить адрес. Вы не можете получить адрес значения «она указывает» eg void foo (int && a) {int * b = & a;} должен работать, я думаю –

+0

То, что вы объяснили выше, я уже понимаю .. но моя проблема заключается в том, только о разнице между этими int & & Rref; // Rref is lvalue ..................... int && Func() // вызов Func is rvalue – Laith

Смежные вопросы