Значение l - это значение, привязанное к определенной области памяти, тогда как значение r - это значение выражения, существование которого является временным и которое не обязательно относится к определенной области памяти.Всякий раз, когда значение lvalue используется в позиции, в которой ожидается значение rvalue, компилятор выполняет преобразование значения lvalue в значение rvalue и затем выполняет оценку.
http://www.eetimes.com/discussion/programming-pointers/4023341/Lvalues-and-Rvalues
Всякий раз, когда мы создаемвременный (анонимный) объект класса или возврат временного объекта класса из функции, хотя объект является временным, он адресуемый.Тем не менее, объект по-прежнему является допустимым значением.Это означает, что объект является a) адресуемым значением r или b) неявно преобразуется из значения l в значение r, когда компилятор ожидает, что будет использоваться значение l.
Например:
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&)
из списка перегруженных конструкторов, возвращенный временный объект все равно соответствовал бы конструктору rvalue-reference A::A(A&&)
.
Это то, что я не совсем понимаю: какможет ли объект a
соответствовать и ссылке rvalue и ссылке lvalue?Ясно, что A::A(A&)
лучше, чем A::A(A&&)
(и поэтому a
должно быть lvalue).Но поскольку ссылка на rvalue не может быть инициализирована значением lvalue, учитывая, что формальный аргумент a
является значением lvalue, она не должна соответствовать вызову A::A(A&&)
.Если компилятор выполняет преобразование lvalue в rvalue, это будет тривиально.Тот факт, что преобразование из 'A' в 'A &' также является тривиальным, обе функции должны иметь одинаковые ранги неявных последовательностей преобразования, и поэтому компилятор не должен иметь возможность определять функцию наилучшего соответствия, когда оба A::A(A&)
и A::A(A&&)
находятся в наборе кандидатов перегруженной функции.
Более того, вопрос (который я ранее задавал):
Как данный объект может соответствовать и ссылке rvalue, и ссылке lvalue?