سؤال

أقوم حاليا بتطوير فئة محلل Syntaxic التي تحتاج، عند نقطة التعليمات البرمجية، إلى فرز المعلومات التي تحمل المعلومات حول المشغلين. لكل مشغل أولوية، والتي يتم تعريفها من خلال وظائف الأعضاء العامة من فئة محلل. وبالتالي، عند الفرز، أحتاج إلى وظيفة الفرز الخاصة بي لطلب العناصر بناء على أولوية المشغل المقابل. أنا أستخدم التعليمات البرمجية التالية لمقارنة العناصر:

bool parser::op_comp(const op_info& o1, const op_info& o2) {
    op_def& op1 = operators[o1.op_char];
    op_def& op2 = operators[o2.op_char];

    return op1.priority > op2.priority;
}

لاحظ أنه اضطررت إلى جعل هذه الوظيفة ثابتة، لأنها محددة داخل فئة.

في الواقع، وظائف بلدي مقارنة يقارن عناصر النوع op_char, ، واسترجع المشغل def من خريطة تحتوي على عناصر من النوع op_def, ، والتي لها مجال "الأولوية".

المشكلة التي أواجهها هي أنني لا أستطيع إدارة الاستخدام std::sort(ops.begin(), ops.end(), std::mem_fun_ref(&parser::op_comp)) (حيث العمليات هي vector of op_info) طريقة. أحصل على الخطأ التالي، الذي يبدو منطقا جدا:

خطأ: استخدام غير صالح للعضو `المحلل :: المشغلون 'في وظيفة العضو الثابت

هنا هو سؤدي: كيف يمكنني إجبار STD :: فرز لاستخدام وظيفة شركات تستفيد عناصر من الأعضاء غير الثابتين في الفصل؟ من الواضح أن الوظيفة يجب أن تكون غير ثابتة، لكنني لا أستطيع أن أتمكن من استخدامها إذا لم أجعلها ثابتة ...

شكرا مقدما على مساعدتكم، CFP.

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

المحلول

استخدم Functor بدلا من الوظيفة:

struct op_comp : std::binary_function<op_info, op_info, bool>
    {
    op_comp(parser * p) : _parser(p) {}
    bool operator() (const op_info& o1, const op_info& o2) {
        return _parser->op_comp(o1, o2);
    }
    parser * _parser;
};

بهذه الطريقة الطريقة op_comp يمكن أن تبقى غير ثابتة. ومع ذلك، يحتاج المتصل إلى مثيل المحلل، حيث يتم تخزين جميع المشغلين. هذا هو استخدام موصلنا الجديد:

std::sort(ops.begin(), ops.end(), op_comp(&my_parser));

أين my_parser هو مثيل المحلل الذي تستخدمه. بدلا من ذلك، إذا كنت تتصل std::sort من المحلل المحلل، يمكنك ببساطة كتابة:

std::sort(ops.begin(), ops.end(), op_comp(this));

نصائح أخرى

جعل المشغلين ثابتة كذلك، وستتمكن من استخدامه في OP_COMP.

بدلا من ذلك، استخدم Functor بدلا من وظيفة:

class myCompareClass {
  public:
  bool operator() (
    const op_info& o1, const op_info& o2) { 
    op_def& op1 = operators[o1.op_char]; 
    op_def& op2 = operators[o2.op_char]; 

    return op1.priority > op2.priority; 
  }
  private:
    ... operators ...
} myCompareObject;

std::sort(ops.begin(), ops.end(), myCompareObject) 

رؤية المزيد من الأمثلة في cplusplus.com.

إذا كنت تريد OP_COMP أن تكون غير ثابتة، يمكنك استخدام Bost.lambda أو Boost.Bind:

parser my_parser;
sort(ops.begin(), ops.end(), bind(&parser::op_comp, ref(my_parser)));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top