"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > كيفية استدعاء دالة على جميع وسيطات القالب المتغير في لغة C++؟

كيفية استدعاء دالة على جميع وسيطات القالب المتغير في لغة C++؟

تم النشر بتاريخ 2024-11-19
تصفح:613

How to Invoke a Function on All Variadic Template Arguments in C  ?

قوالب C المتغيرة: استدعاء دالة على جميع وسيطات القالب

في لغة C، غالبًا ما يكون من المرغوب فيه التكرار من خلال وسيطات القالب المتغير وتنفيذ عملية محددة، مثل الاتصال وظيفة. يمكن تحقيق ذلك باستخدام إما:

C 17 Fold Expression

(f(args), ...);
(f(args), ...);
ومع ذلك، إذا كانت الوظيفة المستدعىة من المحتمل أن ترجع كائنًا مع عامل فاصلة مثقل، يجب عليك استخدام:

((void)f(args), ...);
(f(args), ...);
Pre-C 17 Solution

منهج شائع هو الاستفادة من تهيئة القائمة وتنفيذ التوسيع بداخلها:

{ print(Args)... }
(f(args), ...);
بما أن print() تُرجع فارغة، يمكنك حل المشكلة عن طريق إرجاع int:

{ (print(Args, 0)...
(f(args), ...);
لضمان نجاح ذلك مع أي عدد من الوسائط، يمكنك جعل الحزمة تحتوي دائمًا على عنصر واحد على الأقل:

{ 0, (print(Args), 0)...
(f(args), ...);
يمكنك تغليف هذا النمط في ماكرو قابل لإعادة الاستخدام:

مساحة الاسم لذلك { باستخدام توسيع_نوع = int[]; } #define SO_EXPAND_SIDE_EFFECTS(PATTERN) ::so::expand_type{ 0, ((PATTERN), 0)...
(f(args), ...);
للتعامل مع عوامل الفاصلة المحملة بشكل زائد، يمكنك تعديل الماكرو:

#define SO_EXPAND_SIDE_EFFECTS(PATTERN) \ ::so::expand_type{ 0, ((PATTERN), void(), 0)...
(f(args), ...);
إذا كنت قلقًا بشأن تخصيص الذاكرة غير الضروري، فيمكنك تحديد نوع مخصص يدعم القائمة- التهيئة ولكنها لا تخزن البيانات:

مساحة الاسم لذا { هيكل توسيع_نوع { القالب توسيع_نوع(T&&...) {} };
            
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3