2

Does decltype(1+2) declare an xvalue or or a prvalue?

cppreference says, decltype(expression) will declare: 1. T&& if expression is an xvalue 2. T if expression is an prvalue 3. T& if expression is lvalue

But my question is: how to generate an expression that's an xvalue? I suppose that return value and temp objects should be xvalue, but actually they seem to be xvalue, in my experiment:

struct S{};
S f();
int main()
{
    int i=2;
    decltype(i+1) j=i;
    ++j;
    printf("i=%d\n",i);
    S obj;
    decltype(f()) k=obj;

    return 0;
}

This program compiles: I could judge that

decltype(i+1) declares (i+1) as a prvalue

because if it's an xvalue, then decltype gets T&&, which cannot bind to a left value variable of "i". It's also weird that decltype(f()) is also giving me f() as a prvalue?

So my question is: how to write an expression so that decltype(expression) gives me an xvalue? Thanks.

Hind Forsum
  • 9,717
  • 13
  • 63
  • 119
  • http://en.cppreference.com/w/cpp/language/value_category#xvalue – user2357112 Apr 17 '17 at 02:05
  • 1
    You seem to be confusing several concepts. You cannot "declare" a value category. You declare variables with types. Value categories are properties of expressions. – Kerrek SB Apr 17 '17 at 02:07

2 Answers2

5

Decltype resolves to a type, not an expression - you can't say that it "declares a prvalue" or anything like that.

i+1 is a prvalue, and not an id-expression. So decltype yields a non-reference type: decltype(i+1) j = i; means int j = i;.

The second case is similar; f() is a prvalue, so decltype(f()) is S.

To get decltype(expression) to resolve to an rvalue reference type, the expression must be an xvalue. For example decltype( std::move(f()) ) is S&&.

M.M
  • 138,810
  • 21
  • 208
  • 365
3

Suppose that T is not a reference type. Then:

  • For T f();, the type decltype(f()) is T.
  • For T& f();, the type decltype(f()) is T&.
  • For T&& f();, the type decltype(f()) is T&&.

So the way to get decltype to produce an rvalue reference is to apply it to an xvalue expression, for example, std::move(1 + 2).

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084