Значение l является значением, связанным с определенной областью памяти, тогда как rvalue является значением выражения, существование которого является временным и которое не обязательно относится к определенной области памяти. Всякий раз, когда lvalue используется в позиции, в которой ожидается значение r, компилятор выполняет преобразование lvalue-to-rvalue и затем продолжает оценку.
http://www.eetimes.com/discussion/programming-pointers/4023341/Lvalues-and-Rvalues
Всякий раз, когда мы создаем временный (анонимный) объект класса или возвращаем временный объект класса из функции, хотя объект является временным, он адресуется. Тем не менее, объект по-прежнему является допустимым значением r. Это означает, что объект: a) адресуемое rvalue или b) неявно преобразовывается из lvalue в rvalue, когда компилятор ожидает использования lvalue.
Например:
class A
{
public:
int x;
A(int a) { x = a; std::cout << "int conversion ctor\n"; }
A(A&) { std::cout << "lvalue copy ctor\n"; }
A(A&&) { std::cout << "rvalue copy ctor\n"; }
};
A ret_a(A a)
{
return a;
}
int main(void)
{
&A(5); // A(5) is an addressable object
A&& rvalue = A(5); // A(5) is also an rvalue
}
Мы также знаем, что временные объекты , возвращаемые (в следующем случае a
) функциями: lvalues как этот сегмент кода:
int main(void)
{
ret_a(A(5));
}
выводит следующий результат:
int conversion ctor
lvalue copy ctor
Указывая, что вызов функции ret_a
с использованием фактического аргумента A(5)
вызывает конструктор преобразования A::A(int)
, который строит формальный аргумент функции a
со значением 5.
Когда функция завершает выполнение, она затем создает временный объект a
, используя a
в качестве своего аргумента, который вызывает A::A(A&)
. Однако, если бы мы удалили A::A(A&)
из списка перегруженных конструкторов, возвращаемый временный объект по-прежнему будет соответствовать конструктору reference-reference A::A(A&&)
.
Это то, что я не совсем понимаю: как объект a
может совпадать как с ссылкой rvalue, так и с ссылкой lvalue? Ясно, что A::A(A&)
лучше, чем A::A(A&&)
(и, следовательно, a
должно быть lvalue). Но поскольку ссылка rvalue не может быть инициализирована на lvalue, учитывая, что формальный аргумент a
является lvalue, он не должен соответствовать вызову A::A(A&&)
. Если компилятор делает преобразование lvalue-to-rvalue, это было бы тривиально. Тот факт, что преобразование из "A" в "A &" также тривиально, обе функции должны иметь одинаковые неявные ранжирования последовательностей преобразований, и поэтому компилятор не должен иметь возможности выводить функцию наилучшего соответствия, если оба параметра A::A(A&)
и A::A(A&&)
находятся в наборе кандидатов перегруженной функции.
Кроме того, вопрос (который я ранее задавал):
Как данный объект может совпадать как с ссылкой на rvalue, так и с ссылкой lvalue?