Рассмотрим следующий класс:
class Foo
{
std::string name;
public:
Foo(std::string some_name) : name(std::move(some_name))
{
}
std::string& original_name()
{
return name;
}
std::string copy_of_name() const
{
return name;
}
};
Выражение some_foo.copy_of_name()
является prvalue , потому что copy_of_name
возвращает объект (std::string
)не ссылка.Каждое значение также является значением.(R-значения являются более общими.)
Выражение some_foo.original_name()
является lvalue , поскольку original_name
возвращает ссылку на lvalue (std::string&
).Каждое lvalue также является glvalue.(Glvalues являются более общими.)
Выражение std::move(some_name)
является xvalue , потому что std::move
возвращает rvalue ссылку (std::string&&
).Каждое xvalue также является как glvalue, так и rvalue.
Обратите внимание, что names для объектов и ссылок всегда являются lvalues:
std::string a;
std::string& b;
std::string&& c;
Учитывая приведенные выше объявления, выражения a
, b
и c
являются lvalues.