Why is function parameter always an lvalue?

Viewed 599

I could not wrap my mind around the following statement from Scott Meyer's Effective Modern C++...

it's especially important to bear in mind that a parameter is always an lvalue, even if its type is an rvalue reference. That is given

void f(Widget&& w);

the paramter w is an lvalue, event it s type is rvalue-reference-to-widget.

How come a parameter w is an lvalue, but its type is rvalue-reference-to-widget? When people say w is an lvalue, doesnt that mean that its type is a lvalue type? I am probably missing something.

EDIT: Mant thanks to those who commented...I am still a bit confused. I guess I dont fully understand the definition of these concept involved. What are lvalue, rvalue, lvalue reference, rvalue reference? Are these part of the context free grammar of the c++ language? Do these have anything to with code generation? Can I think of type and value category two separate production rules in the c++ context free grammar? What do they mean?

1 Answers

The type of w is rvalue-reference as you can see in the error message.

#include <iostream>
#include <utility>

class Widget {};

void f(Widget&& w)
{
    std::cout << "HERE " << std::endl;
    return;
}

int main()
{
    Widget ww;
    //f(std::move(ww));
    f(ww);
    return 0;
}

https://godbolt.org/z/T616cq

error: cannot bind rvalue reference of type 'Widget&&' to lvalue of type 'Widget'

However the value category of w is lvalue.

The following expressions are lvalue expressions: (bolding mine)

the name of a variable, a function, a template parameter object (since C++20), or a data member, regardless of type, such as std::cin or std::endl. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression;

Related