C ++, est le type défini: déclaration préalable des objets nécessaires

La dernière fois , nous avons utilisé SFINAE pour déterminer si un type a une définition, et nous l'avons utilisé en combinaison avec if constexpr et des expressions lambda génériques afin que le code puisse utiliser le type s'il est défini, tout en étant accepté par le compilateur (et ignoré) si le type n'est pas défini.

Cependant, il existe plusieurs problèmes avec cette application:

  • Chaque fois que vous devez écrire une struct .
  • Si le type n'existe pas, lorsque vous le nommez, ce type est entré dans l'espace de noms actuel et non dans l'espace de noms dans lequel vous vouliez que le type se trouve.
  • Vous devez utiliser une struct avec un nom non qualifié. Vous ne pouvez pas l'utiliser pour rechercher un type que vous n'avez pas importé dans l'espace de noms actuel.

Nous pouvons résoudre les trois problèmes avec une seule solution: déclarez d'abord le type dans l'espace de noms souhaité.



 // awesome.h namespace awesome { //      struct special { ... }; } //   namespace awesome { //   ,    struct special; } 

Après avoir fait cela, vous n'avez pas besoin d'écrire une struct car la structure a été déclarée. L'utiliser comme paramètre de type de modèle dans call_if_defined ne conduira pas à la création d'une nouvelle déclaration, car tout a déjà été déclaré. Et depuis qu'elle a été déclarée, vous pouvez y accéder via son nom non qualifié, son nom d'espace de noms complet ou tout ce qui se trouve entre les deux. Également via un alias de type ou un type dépendant (malheureusement, ils ne sont pas entre).

 namespace app { void foo() { call_if_defined<awesome::special>([&](auto* p) { //      "awesome::special" // .     "special" //     . using special = std::decay_t<decltype(*p)>; //      "special"   //   "awesome::special". special::do_something(); }); } } 

Ceux qui ont suivi cette série d'articles depuis le tout début ont peut-être remarqué que la méthode call_if_defined pas tout à fait à la version que nous avons écrite plus tôt. La nouvelle version prend en charge plusieurs paramètres de type et appelle un lambda uniquement si tous les types sont définis.

Examinons de plus près:

 template<typename... T, typename TLambda> void call_if_defined(TLambda&& lambda) { if constexpr ((... && is_complete_type_v<T>)) { lambda(static_cast<T*>(nullptr)...); } } 

Les crochets doubles si constexpr ((...)) ont l'air bizarre, mais ils sont obligatoires. Des parenthèses externes sont requises par l' if constexpr , et des parenthèses internes sont requises par une expression de convolution . L'expression de convolution se développe pour

  if constexpr ( (is_complete_type_v<T1> && is_complete_type_v<T2> && ... is_complete_type_v<Tn>)) 

L'appel lambda utilise l' extension de package de paramètres :

  lambda(static_cast<T*>(nullptr)...); 

Il se développe pour

  lambda(static_cast<T1*>(nullptr), static_cast<T2*>(nullptr), ..., static_cast<Tn*>(nullptr)); 

static_cast<T*>(nullptr) répété une fois pour chaque type.

Comme je l'ai noté précédemment, nous pouvons utiliser cette fonction pour appeler le lambda si tous les types sont définis:

 void foo(Source const& source) { call_if_defined<special, magic>( [&](auto* p1, auto* p2) { using special = std::decay_t<decltype(*p1)>; using magic = std::decay_t<decltype(*p2)>; auto s = source.try_get<special>(); if (s) magic::add_magic(s); }); } 

C ++ 20 vous permet de l'écrire comme ceci:

 void foo(Source const& source) { call_if_defined<special, magic>( [&]<typename special, typename magic> (special*, magic*) { auto s = source.try_get<special>(); if (s) magic::add_magic(s); }); } 

ce qui vous permet de nommer le type du modèle, éliminant ainsi la nécessité de le ré-extraire tout en jouant avec std::decay_t .

Dans le prochain article, nous allons l'utiliser comme tremplin et étendre le circuit.



Remarque : il s'agit de la quatrième partie de la série principale d'articles, mais il existe encore d'autres parties ( 1 , 2 , 3 , 5 ). Pour les impatients: voici ce dont vous avez besoin pour copier et coller:

 template<typename, typename = void> constexpr bool is_type_complete_v = false; template<typename T> constexpr bool is_type_complete_v <T, std::void_t<decltype(sizeof(T))>> = true; template<typename... T, typename TLambda> void call_if_defined(TLambda&& lambda) { if constexpr ((... && is_complete_type_v<T>)) { lambda(static_cast<T*>(nullptr)...); } } 

Soit dit en passant, nous avons un travail cool


Depuis plus d'une décennie, Havok est à la pointe de l'innovation dans le développement de jeux et la 3D interactive. Dans le cadre de Cognition, l'équipe HoloLens, nous combinons maintenant cette expertise et la puissance du cloud Azure pour développer de nombreux nouveaux services de réalité mixte passionnants. Parmi eux, le service Azure Remote Rendering récemment annoncé. Nous sommes passionnés par la combinaison des technologies AR, VR et cloud, qui ensemble nous permettent de créer des pratiques innovantes en utilisant la réalité mixte.

Emplois chez Havok:

  • Vous travaillerez en petites équipes avec des développeurs talentueux
  • Vous aurez l'occasion de travailler avec de nouvelles technologies sur une variété de plates-formes et d'appareils matériels.
  • Vous travaillerez sur la résolution de problèmes techniques complexes avec de grandes perspectives
  • Vous collaborerez avec des équipes sympas du monde entier.

Responsabilités


  • Concevoir, développer et tester du code C ++ multiplateforme de haute qualité, efficace et propre
  • Développer des services Azure bien évolutifs
  • Travailler directement avec les clients internes et externes pour stimuler le développement de produits

Qualifications


  • Compétences en programmation et débogage C ++
  • Capacité à travailler en équipe avec un code commun
  • Expérience avec les technologies de cloud et de services distribués (par exemple Azure Batch, Azure Blob Storage, Docker, Telemetry)

Sera un plus


  • C #, ASP.Net, JavaScript, TypeScript, React
  • Moteurs de jeux Unity, Unreal ou associés
  • Découvrez la 3D interactive, la réalité augmentée ou la réalité virtuelle
  • Services réseau et serveur
  • Optimisation des performances

Vous pouvez en savoir plus et soumettre votre candidature ici ou via LinkedIn .

Source: https://habr.com/ru/post/fr459787/


All Articles