# C++ Value categories **[Value categories](https://en.cppreference.com/w/cpp/language/value_category)** classify expressions based on whether they can be used to obtain an object's address and whether they're about to be destroyed. Lvalues have persistent identity and can be referenced; rvalues (temporaries or results of `std::move`) are about to disappear. This distinction enables move semantics and perfect forwarding. Understand value categories to predict which overloads are chosen and how move semantics behave. ## Example This example shows how value categories determine which constructor or assignment operator is called. ```cpp // compile: g++ -std=c++17 -o values values.cpp // run: ./values // description: value categories determine move vs copy semantics #include class Widget { public: Widget() { std::cout << "Default\n"; } Widget(const Widget&) { std::cout << "Copy\n"; } Widget(Widget&&) { std::cout << "Move\n"; } }; int main() { Widget a; // lvalue: default constructor Widget b = a; // lvalue: copy Widget c = Widget(); // rvalue: move (or elision) Widget d = std::move(a); // move: cast lvalue to rvalue return 0; } ```