نوع التصنيف
في لغة البرمجة C++ ، تُستخدم الكلمة المفتاحية decltype (اختصارًا لـ "النوع المُعلن") لتحديد نوع تعبير ما . وقد أُضيفت هذه الكلمة في C++11 ، ويُستخدم استخدامها الأساسي في البرمجة العامة ، حيث يصعب، أو حتى يستحيل، التعبير عن أنواع تعتمد على معلمات القوالب .
مع ازدياد شعبية تقنيات البرمجة العامة خلال تسعينيات القرن الماضي، برزت الحاجة إلى آلية لاستنتاج النوع. قام العديد من مُصنّعي المُترجمات بتطبيق نسخهم الخاصة من هذا العامل، والتي تُسمى عادةً decltype typeof، كما طُوّرت بعض التطبيقات المحمولة ذات الوظائف المحدودة، استنادًا إلى ميزات اللغة الموجودة. في عام ٢٠٠٢، اقترح بيارن ستروستروب إضافة نسخة قياسية من هذا العامل إلى لغة C++، واقترح تسميته "decltype" ليعكس أن هذا العامل سيُنتج "النوع المُعلن" للتعبير.
decltypeصُممت دلالات 's لتناسب كلاً من مطوري المكتبات العامة والمبرمجين المبتدئين. بشكل عام، يتطابق النوع المُستنتج مع نوع الكائن أو الدالة تمامًا كما هو مُعلن في الكود المصدري . ومثل عامل التشغيل sizeof[ 1 ] ، decltypeلا يتم تقييم مُعامل 's.
تُستخدم ميزة ذات صلة، وهي ^^المعامل (الذي تم تقديمه في C++26 )، لاسترجاع قيمة الانعكاس (بيانات تعريف النوع) لأي رمز. [ 2 ]
تحفيز
مع إدخال القوالب في لغة البرمجة C++ ، وظهور تقنيات البرمجة العامة التي روجت لها مكتبة القوالب القياسية ، برزت الحاجة إلى آلية لتحديد نوع التعبير ، والتي يُشار إليها عادةً بـ `type` . في البرمجة العامة، غالبًا ما يكون من الصعب أو المستحيل التعبير عن الأنواع التي تعتمد على معلمات القالب، [ 3 ] [ 4 ] وخاصةً نوع القيمة المُعادة من استدعاءات قوالب الدوال. [ 3 ]typeof
يُوفر العديد من الموردين هذا typeofالمُعامل كإضافة للمُترجم. [ 5 ] في وقت مُبكر من عام 1997، قبل أن تُصبح لغة C++ مُوحدة بالكامل، اقترح برايان باركر حلاً قابلاً للنقل يعتمد على هذا sizeofالمُعامل. [ 5 ] وقد توسع بيل جيبونز في عمله، وخلص إلى أن هذه التقنية لها العديد من القيود، وأنها عمومًا أقل قوة من typeofآلية فعلية. [ 5 ] في مقال نُشر في أكتوبر 2000 في مجلة دكتور دوبز ، لاحظ أندريه ألكسندرسكو أن "وجود مُعامل typeof سيجعل كتابة وفهم الكثير من التعليمات البرمجية النموذجية أسهل". [ 6 ] كما أشار إلى أن "typeof و sizeof يشتركان في نفس الواجهة الخلفية، لأن sizeof يجب أن يحسب النوع على أي حال". [ 6 ] كما أقر أندرو كونيغ وباربرا إي. مو بفائدة هذه الخاصية المُدمجة typeof، مع التحذير من أن "استخدامها غالبًا ما يُؤدي إلى أخطاء برمجية دقيقة، وهناك بعض المشاكل التي لا يُمكنها حلها". [ 7 ] وصفوا استخدام اصطلاحات الأنواع، مثل تعريفات الأنواع التي توفرها مكتبة القوالب القياسية ، بأنها تقنية أكثر قوة وعمومية. [ 7 ] ومع ذلك، جادل ستيف ديوهيرست بأن هذه الاصطلاحات "مكلفة في تصميمها ونشرها"، وأنه "سيكون من الأسهل بكثير ... استخراج نوع التعبير ببساطة". [ 8 ] في مقال نُشر عام 2011 على C++0x ، توقع كونيغ ومو أن "يُستخدم decltype على نطاق واسع لجعل كتابة البرامج اليومية أسهل". [ 9 ]
في عام ٢٠٠٢، اقترح بيارن ستروستروب توسيع لغة C++ بآليات للاستعلام عن نوع التعبير، وتهيئة الكائنات دون تحديد النوع. [ ٣ ] لاحظ ستروستروب أن دلالات حذف المراجع التي يوفرها typeofالمعامل المقدم من مُجمِّعي GCC و EDG قد تكون إشكالية. [ ٣ ] في المقابل، اعتُبر المعامل الذي يُعيد نوع مرجع بناءً على كون التعبير قيمةً يساريةً (lvalue ) مُربكًا للغاية. حدد الاقتراح الأولي المقدم إلى لجنة معايير C++ مزيجًا من المتغيرين؛ حيث يُعيد المعامل نوع مرجع فقط إذا كان النوع المُعلن للتعبير يتضمن مرجعًا. وللتأكيد على أن النوع المُستنتج سيعكس "النوع المُعلن" للتعبير، اقتُرح تسمية المعامل بـ decltype. [ ٣ ]
كان أحد الدوافع الرئيسية المذكورة لهذا decltypeالاقتراح هو القدرة على كتابة قوالب دوال توجيه مثالية. [ 10 ] من المستحسن أحيانًا كتابة دالة توجيه عامة تُرجع نفس نوع الدالة المُغلّفة، بغض النظر عن النوع الذي تم إنشاؤها به. بدون ذلك decltype، لا يمكن تحقيق ذلك عمومًا. [ 10 ] مثال على ذلك، والذي يستخدم أيضًا نوع الإرجاع اللاحق : [ 10 ]
int & foo ( int & i ) { ++ i ; return i ; }float foo ( float & f ) { f += 1.0f ; return f ; }template < class T > auto forwarder ( T & t ) − > decltype ( foo ( t )) { return foo ( t ); }decltypeيُعد هذا الأمر ضروريًا هنا لأنه يحافظ على المعلومات المتعلقة بما إذا كانت الدالة المُغلّفة تُرجع نوع مرجعي. [ 11 ]
علم الدلالة
على غرار sizeofالمعامل ، فإن معامل decltypeغير مُقيَّم، لذا فإن تعبيرات مثل decltype(i++)لن تؤدي إلى زيادة قيمة المتغير i. [ 12 ]decltype(e) بشكل غير رسمي، يتم استنتاج النوع الذي تُرجعه الدالة على النحو التالي: [ 3 ]
- إذا كان التعبير
eيشير إلى متغير في نطاق محلي أو نطاق اسم، أو متغير عضو ثابت، أو مُعامل دالة، فإن النتيجة هي نوع ذلك المتغير أو المُعامل المُعلن عنه - وإلا، إذا
eكانت قيمة lvalue ، فإن النتيجةdecltype(e)هيT&، حيثTيمثل نوع e؛ إذا كانت قيمة xvalue ، فإن النتيجة هيT&&؛ وإلا، فإن e قيمة prvalue والنتيجة هيT. - كحالة خاصة،
decltype(auto)يسمح هذا الأسلوب باستنتاج النوع،autoولكنه يحافظ على فئة قيمة المُهيئ. وبشكل أكثر تحديدًا، فهو يُعادل .decltype(initializer)
صُممت هذه الدلالات لتلبية احتياجات مطوري المكتبات العامة، مع مراعاة سهولة استخدامها للمبرمجين المبتدئين، لأن نوع القيمة المُعادة decltypeيطابق دائمًا نوع الكائن أو الدالة كما هو مُعلن في الكود المصدري. [ 3 ] وبشكل أكثر دقة، تنطبق القاعدة 1 على تعبيرات المعرفات غير المُحاطة بأقواس وتعبيرات الوصول إلى أعضاء الفئة. [ 13 ] [ 14 ] مثال: [ 13 ] ملاحظة للأسطر المُضافة للدالة bar(): النوع المُستنتج للدالة bar() هو عدد صحيح عادي، وليس عددًا صحيحًا ثابتًا، لأن القيم الأولية للأنواع غير المُصنفة لها دائمًا أنواع غير مُؤهلة بـ cv، على الرغم من اختلاف النوع المُعلن عنه بشكل ثابت.
const int & foo () { static int val = 1 ; return val ; }const int bar () { return 1 ; }int i = 0 ;struct Double { double v ; };const Double * d = new Double ();decltype ( foo ()) x1 ; // النوع هو const int& decltype ( bar ()) x2 ; // النوع هو int decltype ( i ) x3 ; // النوع هو int decltype ( d- > i ) x4 ; // النوع هو double decltype (( d- > i )) x5 ; // النوع هو const double&احذف د ؛يكمن سبب الاختلاف بين الاستدعاءين الأخيرين في decltypeأن التعبير الموجود بين قوسين (a->x)ليس تعبيرًا عن هوية ولا تعبيرًا عن الوصول إلى عضو، وبالتالي لا يدل على كائن مُسمى. [ 15 ] ولأن التعبير قيمة قابلة للتعديل، فإن نوعه المُستنتج هو "مرجع إلى نوع التعبير". const double&[ 12 ] قد يُسبب استخدام أقواس إضافية لإدخال مُؤهل مرجعي إلى النوع أخطاءً للمبرمجين الذين لا يفهمون هذه الآلية فهمًا كاملًا decltype. [ 16 ]
في ديسمبر 2008، أثار جاكو يارفي مخاوفه أمام اللجنة بشأن عدم إمكانية استخدام `decltype`decltype لتكوين مُعرّف مؤهل ، [ 1 ] وهو ما يتعارض مع الغرض من معاملته "كما لو كان اسمًا مُعرّفًا لنوع بيانات ". [ 17 ] وأثناء تعليقها على مسودة اللجنة الرسمية لمعيار C++0x ، أشارت الهيئة اليابانية العضو في المنظمة الدولية للمعايير (ISO) إلى أنه "لا يمكن تطبيق عامل النطاق (::) على `decltype`، ولكن ينبغي تطبيقه. سيكون من المفيد في هذه الحالة الحصول على نوع العضو (النوع المُتداخل) من مثيل كما يلي: [ 18 ]decltype(e)
vector <int> v ; decltype ( v ) :: value_type i = 0 ; // int i = 0 ;تمت معالجة هذه المسألة، وقضايا مماثلة تتعلق بالصياغة التي تمنع استخدام decltypeفي تعريف فئة مشتقة وفي استدعاء المدمر ، من قبل ديفيد فانديفورد، وتم التصويت عليها في ورقة العمل في مارس 2010. [ 19 ] [ 20 ]
التوافر
decltypeمُدرجة في معيار لغة C++ منذ C++11 . [ 13 ] تُوفرها العديد من المُترجمات كإضافة. تُوفر مُترجمات Visual C++ 2010 من مايكروسوفت والإصدارات الأحدث مُحدد نوع يُحاكي بدقة الدلالات كما هو موضح في اقتراح لجنة المعايير. يُمكن استخدامه مع كلٍ من التعليمات البرمجية المُدارة والأصلية. [ 11 ] تُشير الوثائق إلى أنه "مفيد بشكل أساسي للمطورين الذين يكتبون مكتبات القوالب". [ 11 ] أُضيف إلى السطر الرئيسي لمُترجم GCC C++ في الإصدار 4.3، [ 21 ] الذي صدر في 5 مارس 2008. [ 22 ] وهو موجود أيضًا في C++ Builder 2009 من Codegear ، [ 23 ] ومُترجم Intel C++ ، [ 24 ] و Clang . [ 25 ]decltypedecltypedecltype
مراجع
- 1 2 ميلر، ويليام م. (29-09-2009). "قضايا اللغة الأساسية في معيار C++، المراجعة 66" . ISO/IEC JTC1/SC22/WG21 - لجنة معايير C++ . تم الاطلاع عليه بتاريخ 03-10-2009 .
- ↑ وايت تشيلدرز وآخرون (26 يونيو 2024). "P2996R4 - الانعكاس لـ C++26" . isocpp.org . WG21.
- 1 2 3 4 5 6 7 جريجور، دوغلاس؛ يارفي، جاكو؛ سيك، جيريمي. ستروستروب ، بيارن (28/04/2003). "Decltype والتلقائي" (PDF) . ISO/IEC JTC1/SC22/WG21 - لجنة معايير C++ . تم الاسترجاع 2015/08/28 .
- ↑ كالف، داني (2008-05-08). "تنظيف فوضى بناء جملة الدالة مع decltype " . DevX.com . تم الاسترجاع في 2009-09-04 .
- 1 2 3 جيبونز، بيل (2000-11-01). "جهاز تشغيل محمول من نوع معين" . مجلة دكتور دوبز . تم الاسترجاع في 2009-09-03 .
- 1 2 ألكسندرسكو، أندريه (2000-10-01). "البرمجة العامة: عمليات الربط بين الأنواع والقيم" . مجلة دكتور دوبز . تم الاسترجاع في 2009-09-03 .
- 1 2 كونيغ، أندرو؛ باربرا إي. مو (2002-02-01). "لغة سي++ أصبحت أسهل: تسمية الأنواع غير المعروفة" . مجلة دكتور دوبز . تم الاسترجاع في 2009-09-03 .
- ↑ ديوهيرست، ستيف (1 أغسطس 2000). "المعرفة العامة: عامل من نوع bitwise، الجزء 1" . مجلة دكتور دوبز . تم الاسترجاع في 3 سبتمبر 2009 .
- ↑ كونيغ، أندرو؛ باربرا إي. مو (19 يوليو 2011). "4 ميزات جديدة مفيدة في C++0x" . مجلة دكتور دوبز . تم الاطلاع عليه بتاريخ 12 يناير 2012 .
- 1 2 3 دوس ريس، غابرييل؛ يارفي، جاكو؛ ستروستروب ، بيارن (2004/10/12). "Decltype and auto (المراجعة 4)" (PDF) . ISO/IEC JTC1/SC22/WG21 - لجنة معايير C++ . تم الاسترجاع 2009-09-04 .
- 1 2 3 "decltype Operator" . شركة مايكروسوفت . تم الاسترجاع في 4 سبتمبر 2009 .
- 1 2 دوس ريس، غابرييل؛ يارفي، جاكو؛ ستروستروب ، بيارن (2007-07-18). "Decltype (المراجعة 7): الصياغة المقترحة" (PDF) . ISO/IEC JTC1/SC22/WG21 - لجنة معايير C++ . تم الاسترجاع 2009-09-04 .
- 1 2 3 بيكر، بيت. "مسودة عمل، معيار للغة البرمجة C++" (ملف PDF) . ISO/IEC JTC1/SC22/WG21 - لجنة معايير C++ . تاريخ الاسترجاع: 4 سبتمبر 2009 .
- ↑ ميلر، ويليام م. (2009-08-03). "تقارير عيوب لغة C++ الأساسية القياسية، المراجعة 65" . ISO/IEC JTC1/SC22/WG21 – لجنة معايير C++ . تم الاطلاع عليه بتاريخ 2009-09-15 .
- ↑ ميلر، ويليام م. (2009-08-03). "مسائل مغلقة في لغة C++ الأساسية القياسية، المراجعة 65" . ISO/IEC JTC1/SC22/WG21 – لجنة معايير C++ . تم الاطلاع عليه بتاريخ 2009-09-04 .
- ↑ مازيير، ديفيد (يونيو 2021). "تبسيط فئات القيم في لغة C++ و decltype" . تم الاسترجاع في 16 يونيو 2022 .
- ^ دوس ريس، غابرييل. يارفي، جاكو؛ ستروستروب ، بيارن (2006/11/05). "Decltype (المراجعة 6): الصياغة المقترحة" (PDF) . ISO/IEC JTC1/SC22/WG21 - لجنة معايير C++ . تم الاسترجاع 2009-10-03 .
- ↑ ميلر، ويليام م. (2009-08-03). "حالة التعليقات على معيار C++ CD1" . اللجنة الفنية المشتركة 1/اللجنة الفرعية 22/مجموعة العمل 21 التابعة للمنظمة الدولية للمعايير/اللجنة الكهروتقنية الدولية - لجنة معايير C++ . تم الاطلاع عليه بتاريخ 2009-10-03 .
- ↑ ميلر، ويليام م. (29-03-2010). "تقارير عيوب لغة C++ الأساسية القياسية، المراجعة 69" . ISO/IEC JTC1/SC22/WG21 – لجنة معايير C++ . تم الاطلاع عليه بتاريخ 10-04-2010 .
- ↑ فانديفورد، دافيد (2010-02-03). "المشكلتان الأساسيتان 743 و950: استخدامات إضافية لـ decltype(...)" (ملف PDF) . ISO/IEC JTC1/SC22/WG21 - لجنة معايير لغة C++ . تاريخ الاسترجاع: 2010-04-10 .
- ↑ "دعم C++0x في GCC" . مؤسسة البرمجيات الحرة . 27-08-2009 . تم الاطلاع عليه بتاريخ 04-09-2009 .
- ↑ "سلسلة إصدارات GCC 4.3" . مؤسسة البرمجيات الحرة . 13 أغسطس 2009. تم الاطلاع عليه بتاريخ 4 سبتمبر 2009 .
- ↑ "محدد النوع decltype (C++0x)" . شركة إمباركاديرو تكنولوجيز. مؤرشف من الأصل بتاريخ 2011-07-08 . تم الاطلاع عليه بتاريخ 2009-09-04 .
- ↑ "std, Qstd" . شركة إنتل . تم الاسترجاع في 4 سبتمبر 2009 .
- ↑ غريغور، دوغلاس (26 يناير 2011). "دعم ميزات C++0x الجديدة في Clang" . مؤرشف من الأصل في 30 يناير 2011.
روابط خارجية
- لغة سي++
