Namespaces
Variants

opérateur de réflexion (depuis C++26)

Depuis fr.cppreference.net
 
 
Langage C++
Sujets généraux
Contrôle de flux
Instructions d'exécution conditionnelle
si
Instructions d'itération (boucles)
pour
plage-for (C++11)
Instructions de saut
Fonctions
Déclaration de fonction
Expression de fonction lambda
inline spécificateur
Spécifications d'exception dynamique (jusqu'à C++17*)
noexcept spécificateur (C++11)
Exceptions
Espaces de noms
Types
Spécificateurs
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Spécificateurs de durée de stockage
Initialisation
Expressions
Représentations alternatives
Littéraux
Booléen - Entier - Virgule flottante
Caractère - Chaîne - nullptr (C++11)
Défini par l'utilisateur (C++11)
Utilitaires
Attributs (C++11)
Types
typedef déclaration
Déclaration d'alias de type (C++11)
Conversions
Allocation mémoire
Classes
Propriétés de fonction spécifiques à la classe
Fonctions membres spéciales
Modèles
Divers
 
 

L'opérateur unaire ^^ opérateur, appelé l'opérateur de réflexion, produit la réflexion du construct linguistique donné, de type std::meta::info.

Syntaxe

^^ :: (1)
^^ reflection-name (2)
^^ type-id (3)
^^ id-expression (4)
reflection-name - un identifiant, éventuellement qualifié, éventuellement en utilisant le désambiguïsateur de modèle. Cette forme a priorité sur type-id et id-expression
type-id - un type-id
id-expression - un id-expression

La plus longue séquence de jetons pouvant syntaxiquement former l'opérande de ^^ est analysée. Si le résultat représente un modèle, l'expression ne doit pas être directement suivie de <.

static_assert(std::meta::is_type(^^int())); // ^^int() represents the type int()
                                            // not a function call to ^^int

template<bool> struct X {};
consteval bool operator<(std::meta::info, X<false>) { return false; }
consteval void g(std::meta::info r, X<false> xv) {
    r == ^^int && true; // error: ^^ applies to the type-id int&&
    r == ^^int & true; // error: ^^ applies to the type-id int&
    r == (^^int) && true; // OK
    r == ^^int &&&& true; // error: int &&&& is not a valid type-id
    ^^X < xv; // error: reflect-expression that represents a template is followed by <
    (^^X) < xv; // OK
    ^^X<true> < xv; // OK
}

Explication

1) L'expression ^^:: représente l'espace de noms global.
2) Dans ^^reflection-name, le reflection-name est recherché, et la représentation est déterminée comme suit :
  • Si le désambiguïsateur de modèle est présent, le résultat représente le modèle de classe nommé par le nom-de-classe injecté.
  • Sinon, le nom-de-classe injecté doit être non ambigu lorsqu'il est considéré comme un nom de type (sinon l'expression est invalide). Le résultat représente le type ainsi nommé.
  • Sinon, si la recherche trouve un ensemble de surcharges, cet ensemble de surcharges ne doit contenir que des déclarations d'un modèle de fonction unique. Le résultat représente ce modèle de fonction.
  • Sinon, si la recherche trouve un modèle de classe, un modèle de variable, ou un modèle d'alias, le résultat représente ce modèle.
template<typename T>
struct S {
    static constexpr std::meta::info r = ^^T;
    using type = T;
};
static_assert(S<int>::r == ^^int); // OK
static_assert(^^S<int>::type != ^^int); // OK

typedef struct X {} Y;
typedef struct Z {} Z;
constexpr std::meta::info e = ^^Y; // OK, represents the type alias Y
constexpr std::meta::info f = ^^Z; // OK, represents the type alias Z, not the type
  • Sinon, si la recherche trouve un type de classe ou un type d'énumération, le résultat représente ce type.
  • Sinon, si la recherche trouve un membre de classe d'une union anonyme, le résultat représente ce membre.
  • Sinon, le reflection-name est considéré comme un id-expression (voir la forme (4) ci-dessous).
3) L'expression ^^type-id représente une entité déterminée comme suit :
  • Si le type-id désigne un type placeholder (par exemple auto), l'expression est invalide.
  • Sinon, si le type-id nomme un modèle d'alias avec une liste d'arguments de modèle, le résultat représente l'alias de type ainsi nommé. (Les autres formes de noms d'alias de type seraient traitées comme un reflection-name et le résultat représenterait également l'alias de type.)
  • Sinon, le résultat représente le type désigné par le type-id.
4) L'expression ^^id-expression représente une entité déterminée comme suit :
  • Si le id-expression désigne :
l'expression est invalide.
  • Sinon, si le id-expression désigne un ensemble de surcharges, la résolution de surcharge doit sélectionner une fonction unique. Le résultat représente cette fonction.
template<typename T> void fn() requires (^^T != ^^int);
template<typename T> void fn() requires (^^T == ^^int);
template<typename T> void fn() requires (sizeof(T) == sizeof(int));
constexpr std::meta::info a = ^^fn<char>; // OK
constexpr std::meta::info b = ^^fn<int>;  // error: ambiguous

L'opérande est un opérande non évalué.

Notes

Une valeur de réflexion peut également être produite par std::meta::reflect_constant, std::meta::reflect_object, std::meta::reflect_function, ou en initialisant par défaut std::meta::info. De plus, une valeur de réflexion peut être obtenue en appelant des <fonctions méta> avec des objets std::meta::info existants.

Si un alias de type apparaît dans le cadre d'un type-id, l'opérateur de réflexion ne préserve pas l'alias de type.

using T = int;
static_assert(^^T != ^^int);
static_assert(^^T& == ^^int&);
static_assert(^^T const == ^^const int);

Exemple

int arr[] = {1, 2, 3};
auto [a1, a2, a3] = arr;
[[=1]] void fn(int n);
enum Enum { A };
using Alias = int;
struct S { int mem; };
template<auto> struct TCls {};
template<auto> void TFn();
template<auto> int TVar;
template<auto N> using TAlias = TCls<N>;
template<auto> concept Concept = true;
namespace NS {}
namespace NSAlias = NS;

constexpr auto r_arr   = ^^arr; // represents a variable
constexpr auto r_sb    = ^^a3; // represents a structured binding
constexpr auto r_fn    = ^^fn; // represents a function
constexpr auto r_enum  = ^^Enum::A; // represents an enumerator
constexpr auto r_alias = ^^Alias; // represents a type alias
constexpr auto r_type  = ^^S; // represents a type
constexpr auto r_mem   = ^^S::mem; // represents a class member
constexpr auto r_tcls  = ^^TCls; // represents a class template
constexpr auto r_tfn   = ^^TFn; // represents a function template
constexpr auto r_tvar  = ^^TVar; // represents a variable template
constexpr auto r_ttype = ^^TAlias; // represents an alias template
constexpr auto r_cncpt = ^^Concept; // represents a concept
constexpr auto r_ns    = ^^NS; // represents a namespace
constexpr auto r_ns2   = ^^NSAlias; // represents a namespace alias

int main() {}

Voir aussi

renvoie une réflexion représentant une valeur ou un objet paramètre de modèle, adapté à une utilisation comme argument de modèle constant
(modèle de fonction)
renvoie une réflexion représentant un objet, adapté à une utilisation comme argument de modèle constant
(modèle de fonction)
renvoie une réflexion représentant une fonction, adapté à une utilisation comme argument de modèle constant
(modèle de fonction)