Unicorn with delicious cookie
Nous utilisons des cookies pour améliorer votre expérience de navigation. En savoir plus
Accepter
to the top
>
>
>
Expressions: value categories and refer…

Expressions: value categories and reference types

17 Sep 2021

Each expression in C++ has two properties – a type and a value category. Depending on the value category, a reference of a certain kind may be bound to an expression.

Value categories

Before move semantics, there were two categories of expressions in C++ – lvalue and rvalue. To differentiate between lvalue and rvalue, the following rule was used: if an expression could appear on the left-hand side of an assignment expression, then it is lvalue. Otherwise, it is rvalue.

The C++11 standard introduced new value categories to support move semantics – glvalue, prvalue, and xvalue. Now any expression can belong to one of these categories.

An rvalue is a union of prvalue and xvalue. An glvalue is a union of lvalue and xvalue.

The C++ standard does not give an official definition of categories. The paper specifies which value category each expression type has.

To differentiate between lvalue, xvalue and prvalue, you can use the following rule:

  • An expression is a prvalue if it is a temporary unnamed object. For example, i++.
  • An expression is an xvalue if it is a named object whose resources can be reused. An expression is also an xvalue if it is the result of the static_cast<type &&> expression or the result of calling a function that returns type &&. For example, std::move (obj).
  • All other expressions are lvalue. For example, *ptr.

Reference kinds

Before C++11, there was only one reference kind. If you wanted to take a reference to the var variable of the type type, you had to write the following:

type &ref = var;

Such a reference is called an lvalue reference. It can be bound only to an lvalue expression.

To support move semantics, new reference types became available – an rvalue reference and a forwarding reference. If an rvalue reference is required, you must write the following:

type &&ref = rvalue_expr;

Such reference, unlike an lvalue reference, must refer to an rvalue expression.

A forwarding reference is now available:

template <typename T>
void foo(T &&arg);

where T is the template parameter derived from the function template argument. Such declaration looks like an rvalue reference declaration, but it functions differently. Due to reference collapsing, a forwarding reference can be bound to lvalue and rvalue objects. Here is the detailed description of this mechanism.

Do not confuse forwarding and rvalue references. In the example below, the T template parameter corresponds to the Base class, not to the foo function. Therefore, the arg argument of the foo function is an rvalue reference, not a forwarding one:

template <typename T>
class Base
{
  void foo(T&& arg);
};

A forwarding reference allows implementing perfect forwarding. This mechanism is responsible for moving an object of a certain type as expected: an rvalue object is moved, an lvalue object is copied. The std::forward function is the implementation of perfect forwarding in the standard library.

Popular related articles

S'abonner

Comments (0)

close comment form
close form

Remplissez le formulaire ci‑dessous en 2 étapes simples :

Vos coordonnées :

Étape 1
Félicitations ! Voici votre code promo !

Type de licence souhaité :

Étape 2
Team license
Enterprise licence
** En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité
close form
Demandez des tarifs
Nouvelle licence
Renouvellement de licence
--Sélectionnez la devise--
USD
EUR
* En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité

close form
La licence PVS‑Studio gratuit pour les spécialistes Microsoft MVP
close form
Pour obtenir la licence de votre projet open source, s’il vous plait rempliez ce formulaire
* En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité

close form
I want to join the test
* En cliquant sur ce bouton, vous déclarez accepter notre politique de confidentialité

close form
check circle
Votre message a été envoyé.

Nous vous répondrons à


Si l'e-mail n'apparaît pas dans votre boîte de réception, recherchez-le dans l'un des dossiers suivants:

  • Promotion
  • Notifications
  • Spam