Насколько я знаю, со времен C++11 появились такие понятия: lvalue, rvalue, prvalue, xvalue и т.д.
Насколько я понимаю, если функция возвращает локальную переменную, она должна быть rvalue.
std::string func() { return std::string("abc"); }
auto ret = func(); // func returns a rvalue
А для xvalue std::move(x)
— это своего рода xvalue.
Думаю, я прав.
Сегодня мой коллега сказал мне, что мы не можем получить адрес rvalue, поэтому &func()
недопустимо, но мы можем получить адрес xvalue. Это способ различить rvalue и xvalue...
Ну, я только что попробовал: int a = 1; std::cout << &std::move(a);
. Но компилятор сказал:
error: taking address of xvalue (rvalue reference)
Значит, мой коллега не прав?
ОБНОВИТЬ
На самом деле, мой коллега неправильно понял значение «имеет личность» и унарный оператор &
, и он меня смущает...
Вот очень хороший вопрос по этой проблеме: Что значит «xvalue имеет идентичность»?
Ваш коллега не прав. C++ всегда требовал lvalue для использования с адресом оператора. Это явно вызывается в [expr.unary.op]/3:
The operand of the unary
&
operator shall be an lvalue of some typeT
. The result is a prvalue.
Если бы стандарт использовал glvalue
вместо lvalue
, то они были бы правильными, но согласно [рис.:basic.lval]lvalue
и xvalue
являются отдельными листьями glvalue
, поэтому xvalue
не разрешены.
Да, ты прав. На самом деле мой коллега просто неправильно понял значение слова "имеет личность"... Вот хороший вопрос по этому поводу: stackoverflow.com/questions/50783525/…
Мое личное мнение: теоретически C++ мог был разработан, чтобы разрешить
&
для значений x. Действительно, мы можем написатьT* get_addr(T&& y) { return &y; }
, а затем использоватьget_addr(std::move(x))
, так что определение&std::move(x)
таким образом выглядит осуществимым. Однако стоит ли брать адрес объекта истекающий? НаписаниеT* p = get_addr(std::move(x));
создает висячий указатель (бессмысленно). Чтобы избежать этого, мы могли бы продлить время жизни xvalue, привязав его к ссылке, но в этот момент у нас есть lvalue для использования&
. Похоже, что разрешение&xvalue()
в большинстве случаев будет только вредным.