سؤال

أنا أستخدم قوالب C++ لتمرير وظائف الإستراتيجية لتغيير سلوك وظيفتي.أنه يعمل بشكل جيد.العامل الذي أقوم بتمريره هو فئة عديمة الحالة ولا تحتوي على مساحة تخزين، وهو يؤدي فقط إلى زيادة التحميل على المشغل () بالطريقة الوظيفية الكلاسيكية.

template <typename Operation> int foo(int a) 
{
int b=Operation()(a);
/* use b here, etc */
}

أفعل هذا كثيرًا، وهو يعمل بشكل جيد، وغالبًا ما أقوم بإنشاء قوالب تحتوي على 6 أو 7 عوامل نموذجية تم تمريرها!

ومع ذلك فأنا أشعر بالقلق بشأن أناقة الكود وكذلك الكفاءة.العامل عديم الحالة، لذا أفترض أن مُنشئ Operation() مجاني وتقييم العامل بنفس كفاءة الوظيفة المضمنة، ولكن مثل جميع مبرمجي C++، لدي دائمًا بعض الشكوك المزعجة.

سؤالي الثاني هو ما إذا كان بإمكاني استخدام نهج وظيفي بديل..واحد لا يتجاوز عامل التشغيل ()، ولكنه يفعل كل شيء في المُنشئ كأثر جانبي!شيء مثل:

struct Operation {
  Operation(int a, int &b) { b=a*a; }
};
template <typename Operation> int foo(int a) 
 {
   int b;
   Operation(a,b);
    /* use b here, etc */
 }

لم يسبق لي أن رأيت أي شخص يستخدم المُنشئ باعتباره "عملًا" للعامل، ولكن يبدو أنه يجب أن يعمل.هل هناك أي ميزة؟أي عيب؟أنا أحب إزالة الأقواس المزدوجة الغريبة "Operator()(a)" ، ولكن من المحتمل أن يكون هذا مجرد جمالية.

هل كانت مفيدة؟

المحلول

أي عيب؟

  • لا يُرجع Ctors أي قيمة مفيدة -- لا يمكن استخدامه في الاستدعاءات المتسلسلة (على سبيل المثال:فو (شريط ()).
  • يمكنهم رمي.
  • وجهة نظر التصميم - العوامل هي وظائف إنشاء الكائنات، وليس المقصود منها حقًا أن تكون بمثابة قوة عمل.

نصائح أخرى

  1. يقوم المترجمون فعليًا بتضمين المُنشئ الفارغ للعملية (على الأقل gcc في مواقف مماثلة، إلا عند إيقاف تشغيل التحسين)
  2. عيب القيام بكل شيء في المنشئ هو أنه لا يمكنك إنشاء عامل به بعض الحالات الداخلية بهذه الطريقة - على سبيل المثال.دالة لحساب عدد العناصر التي تلبي المسند.أيضًا، استخدام طريقة كائن حقيقي كممثل يسمح لك بتخزين مثيله للتنفيذ لاحقًا، وهو أمر لا يمكنك فعله باستخدام أسلوب المنشئ الخاص بك.

ومن بوف أداء أثبتت رمز مع الحصول الأمثل تماما مع كل VC ودول مجلس التعاون الخليجي. ومع ذلك، فإن أفضل استراتيجية في كثير من الأحيان إلى اتخاذ functor كمعلمة، وبهذه الطريقة يمكنك الحصول على الكثير من المرونة وخصائص الأداء متطابقة.

وأنا أنصح تحديد functor التي تعمل مع المحكمة الخاصة بلبنان الحاويات، أي أنها ينبغي أن تنفذ مشغل (). (بعد API من اللغة التي تستخدمها دائما فكرة جيدة).

وهذا يسمح الخوارزميات الخاصة بك لتكون عامة جدا (تمر في وظائف، [فونكتورس]، STL-ربط وتعزيز :: وظيفة، وتعزيز :: ربط وتعزيز :: امدا، ...) وهو ما من أحد يريد عادة.

وبهذه الطريقة، لا تحتاج لتحديد نوع functor كمعلمة قالب، فقط بناء مثيل وتمريرها في:

my_algorithm(foo, bar, MyOperation())

وهناك لا يبدو أي نقطة في تنفيذ منشئ في فئة أخرى.
كل ما تقوم به هو كسر التغليف ووضع صفك لسوء المعاملة.

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

ويجب أن تكون الطبقة بذاته وتهيئة نفسها إلى حالة جيدة. ما يبدو أنك تقوم به هو اللعب مع القوالب فقط لرؤية ما يمكن القيام به.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top