Классы, Rvalues ​​и Rvalue Ссылки

lvalue - это значение, привязанное к определенной области памяти, тогда как rvalue - это значение выражения, существование которого является временным и которое не обязательно относится к окончательной области памяти. Каждый раз, когда lvalue используется в позиции, в которой ожидается rvalue, компилятор выполняет преобразование lvalue-to-rvalue, а затем продолжает оценку.

http://www.eetimes.com/discussion/programming-pointers/ 4023341 / Lvalues-and-Rvalues ​​

Каждый раз, когда мы создаем временный (анонимный) объект класса или возвращаем временный объект класса из функции, хотя этот объект является временным, он адресуем. Однако объект по-прежнему является допустимым rvalue. Это означает, что объект является 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 ), являются lvalue как этот сегмент кода:

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 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?

13
задан Howard Hinnant 11 March 2011 в 01:11
поделиться