C ++ ، ما إذا كان يتم تعريف النوع: الإعلان الأولي للكائنات الضرورية

آخر مرة ، استخدمنا SFINAE لمعرفة ما إذا كان للنوع تعريف ، واستخدمناه مع if constexpr lambda العامة بحيث يمكن للكود استخدام النوع إذا تم تعريفه ، مع استمرار قبول المترجم (و تجاهل) إذا كان النوع غير محدد.

ومع ذلك ، هناك العديد من المشاكل مع هذا التطبيق:

  • في كل مرة تحتاج إلى كتابة هيكل.
  • في حالة عدم وجود النوع ، ثم تعيين اسم له ، يتم إدخال هذا النوع في مساحة الاسم الحالية ، وليس في مساحة الاسم التي تريد أن يكون النوع بها.
  • تحتاج إلى استخدام struct مع اسم غير مؤهل. لا يمكنك استخدامه للبحث عن نوع لم تستورده في مساحة الاسم الحالية.

يمكننا حل جميع المشكلات الثلاث بحل واحد: أولاً قم بتعريف النوع في مساحة الاسم المطلوبة.



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

بعد القيام بذلك ، لن تحتاج إلى كتابة struct لأنه تم الإعلان عن الهيكل. لا يؤدي call_if_defined كمعلمة لنوع القالب في call_if_defined إلى إنشاء إعلان جديد ، حيث تم بالفعل الإعلان عن كل شيء. ومنذ إعلانها ، يمكنك الوصول إليها من خلال اسمها غير المشروط ، أو اسم مساحة الاسم الكامل ، أو من خلال أي شيء بينهما. وأيضًا من خلال الاسم المستعار للنوع أو النوع التابع (لسوء الحظ ، فهي ليست بين).

 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(); }); } } 

ربما لاحظ أولئك الذين call_if_defined هذه السلسلة من المقالات من البداية أن طريقة call_if_defined تمامًا مع الإصدار الذي call_if_defined سابقًا. الإصدار الجديد يدعم العديد من معلمات الكتابة ويستدعي lambda فقط إذا تم تعريف جميع الأنواع.

دعنا نلقي نظرة فاحصة:

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

الأقواس المزدوجة في حالة كون constexpr ((...)) تبدو غريبة ، لكنها مطلوبة. الأقواس الخارجية مطلوبة بواسطة if constexpr ، والأقواس الداخلية مطلوبة بتعبير الالتفاف . تعبير الإلتواء يمتد إلى

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

يستخدم استدعاء lambda ملحق حزمة المعلمة :

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

انها تتسع ل

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

حيث يتكرر static_cast<T*>(nullptr) مرة واحدة لكل نوع.

كما أشرت سابقًا ، يمكننا استخدام هذه الوظيفة للاتصال بـ lambda إذا تم تحديد جميع الأنواع:

 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 أن تكتبها هكذا:

 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); }); } 

الذي يسمح لك بتسمية نوع القالب ، مما يلغي الحاجة إلى إعادة استخراجه أثناء اللعب باستخدام std::decay_t .

في المقالة التالية ، سوف نستخدم هذا كنقطة انطلاق وتمديد الدائرة.



ملاحظة : هذا هو الجزء الرابع من سلسلة المقالات الرئيسية ، ولكن لا تزال هناك أجزاء أخرى ( 1 ، 2 ، 3 ، 5 ). من أجل الصبر: إليك ما تحتاج إلى نسخه ولصقه:

 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)...); } } 

بالمناسبة ، لدينا وظيفة رائعة


لأكثر من عقد من الزمان ، كانت هافوك في طليعة الابتكار في تطوير اللعبة والأبعاد ثلاثية الأبعاد التفاعلية. كجزء من Cognition ، فريق HoloLens ، نجمع الآن بين هذه الخبرة وقوة سحابة Azure لتطوير العديد من خدمات الواقع المختلط المثيرة. من بينها خدمة Azure Remote Rendering المعلن عنها مؤخرًا. نحن متحمسون للجمع بين تقنيات AR و VR والسحابية ، والتي تتيح لنا معًا إنشاء ممارسات مبتكرة باستخدام الواقع المختلط.

وظائف في Havok:

  • سوف تعمل في فرق صغيرة مع المطورين الموهوبين
  • ستكون لديك الفرصة للعمل مع التقنيات الجديدة على مجموعة متنوعة من الأنظمة الأساسية للأجهزة والأجهزة.
  • سوف تعمل على حل المشكلات الفنية المعقدة ذات الآفاق الكبيرة
  • سوف تتعاون مع فرق رائعة في جميع أنحاء العالم.

الواجبات


  • تصميم وتطوير واختبار رمز C ++ متعدد المنصات عالي الجودة وفعال ونظيف
  • تطوير خدمات أزور جيدة التدرج
  • العمل مباشرة مع العملاء الداخليين والخارجيين لتحفيز تطوير المنتجات

مؤهلات


  • C + + البرمجة ومهارات التصحيح
  • القدرة على العمل في فريق برمز مشترك
  • تجربة مع تقنيات الخدمة السحابية والموزعة (مثل Azure Batch و Azure Blob Storage و Docker و Telemetry)

سوف يكون زائد


  • C # ، ASP.Net ، JavaScript ، TypeScript ، React
  • محركات لعبة Unity أو Unreal أو ذات صلة
  • تجربة 3D التفاعلية ، AR أو VR
  • خدمات الشبكة والخوادم
  • تحسين الأداء

يمكنك معرفة المزيد وإرسال طلبك هنا أو من خلال LinkedIn .

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


All Articles