Почему lvalue не может изменить себя. Что значит пользователь lvalue? - PullRequest
2 голосов
/ 17 октября 2019

Я видел эту цитату из оригинальной статьи:

Когда мы запускаем сортировку по r-значению, можно безопасно отсортировать элемент данных напрямую. Объект является rvalue, что означает, что у него нет других пользователей, поэтому мы можем изменить сам объект. Когда мы запускаем сортировку по const rvalue или lvalue, мы не можем изменить этот объект, поэтому копируем данные перед сортировкой

Он говорит, что rvalue (временная) может сортировать себя, потому чтоне имеет пользователяLvalue не может сортировать себя (сортировать копию), потому что, возможно, у него есть пользователи.

Что такое пользователь lvalue? А что за фон?

Вот код, иллюстрирующий ситуацию.

#include <vector>
#include <algorithm>

using namespace std;

class Foo {
public:
    Foo() { std::cout << "default construct" << std::endl;}
    Foo(const Foo &f) : data(f.data) {std::cout << "copy construct" << std::endl;}
    Foo sort() &&;
    Foo sort() const &;
private:
    vector<int> data;
};

Foo Foo::sort() && {
    std::cout << "rvalue sort" << std::endl;
    std::sort(data.begin(), data.end());
    return *this;
}

Foo Foo::sort() const & {
    std::cout << "lvalue sort" << std::endl;
    return Foo(*this).sort();
}

1 Ответ

0 голосов
/ 17 октября 2019

Ссылка rvalue - это объект, на который больше нельзя ссылаться. Поскольку на объект больше не ссылаются, все, что удерживает объект, может быть видоизменено или перемещено к другому объекту, не затрагивая существующую ссылку на объект (на него больше не ссылаются). Это учитывает семантику перемещения, что означает, что вместо этого можно перемещать данные, которые обычно должны быть скопированы в другой объект.

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

int main(int argc, char *argv[]) {  

  Foo x, y, z;

  std::cout << "lvalue" << std::endl;

  y = x.sort();

  std::cout << "rvalue reference" << std::endl;

  z = Foo().sort();

  return 0;
}

у нас есть

default construct
default construct
default construct
lvalue
lvalue sort
copy construct
rvalue sort
copy construct
rvalue reference
default construct
rvalue sort
copy construct

Сначала произойдет lvalue с вызываемым методом sort, который копируется и становится ссылкой rvalue, а затем сортируется.

ЧтоВторым случаем является то, что созданный объект по умолчанию не имеет имени, поэтому его можно рассматривать как ссылку rvalue. Итак, метод rvalue reference sort вызывается напрямую.

...