سؤال

Boost Lambda يسمح بالكتابة المرتفعة نوع الإرجاع المستخلص باستخدام ret<T> قالب. لقد حاولت البحث عن ما يعادلها في فينيكس ولكن لم أتمكن من العثور على واحدة.

هل هناك ما يعادل في فينيكس؟ أعرف كيف أجعل استبدال خاص بي لكنني أفضل. شكرا لك

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

المحلول

إعادة الكتابة: فاتني النقطة في إجابتي الأولى (لقد تأخرت) ، دعني أحاول مرة أخرى.

اسمحوا لي أن أعطي بعض المعرض لأشخاص مثلي الذين قد يفوتون وجهة نظرك في المرة الأولى. في Boost :: Lambda ، عند استخدام أنواع محددة المستخدم في تعبيرات المشغل ، يتعين على المرء استخدام وظيفة Ret <> لتجاوز خصم نوع الإرجاع. هذا لأن نظام خصم نوع Lambda لإرجاع نوع يدعم فقط أنواع الأصلية (و STL؟ لا أتذكر) أنواعها مباشرة. مثال قصير:

using namespace boost::lambda;

struct add_t{
    add_t(int i) : i(i) {};
    add_t operator+(const add_t& other) const{
        return add_t(i + other.i);
    }
    int i;
};

(_1 + _2)(add_t(38), add_t(4));           // RETURN TYPE DEDUCTION FAILS
ret<add_t>(_1 + _2)(add_t(38), add_t(4)); // OK

في Phoenix ، لا توجد حاجة إلى تلميحات (لاحظ أن الحرفيين وغير المعدنيين لا يمكن أن يظهروا في قائمة وسيطة فينيكس):

using namespace boost::phoenix;

add_t i(38), j(4);
(_1 + _2)(i, j);    // JUST FINE

نظام خصم نوع الإرجاع مختلف تمامًا وأكثر طبيعية في فينيكس ؛ سوف تستنتج بشكل صحيح نوع العائد من المشغلين الذين يستخدمون الدلالات التقليدية. على وجه التحديد ، يجب أن يتطابق نوع الإرجاع مع نوع أحد المعاملات ، أو يكون مرجعًا أو مؤشرًا أو مؤشرًا إلى أحد أنواع الوسيطة ، أو يكون حاوية/حاوية STL لأحد هذه الأنواع. هناك كتابة لطيفة لخصم نوع عودة فينيكس في type_deduction.hpp header لمزيد من التفاصيل.

الآن أنا أقرأ سؤالك ، كيف يمكن التعامل مع دلالات المشغل غير التقليدية في فينيكس؟

النظر في الزوج الغريب التالي من الأنواع كمثال

struct add_ret_t{
    add_ret_t(int i) : i(i) {};
    int i;
};

struct add_t{
    add_t(int i) : i(i) {};
    add_ret_t operator+(const add_t& other) const{
        return add_ret_t(i + other.i);
    }
    int i;
};

بالنسبة إلى Lambda ، هذه ليست مشكلة ، فقط استخدم وظيفة RET:

using namespace boost::lambda;

ret<add_ret_t>(_1 + _2)(add_t(38), add_t(4)); // OK

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

بدلاً من ذلك ، اكتشفت القليل من الاختراق لتجاوز أنواع العائد لمشغلين محددين. نتائج_عملية هياكل القالب في التعزيز/الروح/المنزل/فينيكس/المشغل/الحساب. HPP (الخطوط 39-56 قائمة أنواع الهيكل ، Boost 1.43) تنفيذ خصم النوع عند إنشاء مثيل له وتخزين النتيجة. لذلك كل ما هو مطلوب هو توفير بعض تخصصات القالب لعمليات المشكلات ، والتي تحتاج فقط تحتوي على typedef واحد يحدد نوع الإرجاع. مثال (CODEPAD لـ SRC الكامل):

using namespace boost::phoenix;

namespace boost{ namespace phoenix{

//override add_t addition to give add_ret_t
template <> struct result_of_plus<add_t&, add_t&> { typedef add_ret_t type; };

//override int addition to give char
template <> struct result_of_plus<int&, int&> { typedef char type; };

}}

int main()
{
    add_t i = 1, j = 7;
    std::cout << ((_1 + _2)(i, j)).i << std::endl;

    int k = 51, l = 37;
    std::cout << ((_1 + _2)(k, l)) << std::endl;

    return 0;
}

هذا بالتأكيد ليس بديلاً لـ Ret ، ولكن في بعض الحواس أفضل منذ عالمي. إذا كان هناك الكثير من المشغلين للحمل الزائد ، فيمكن أن تكون المجموعة الكاملة من العمليات ماكرو.

نصائح أخرى

AFAIK ، هذا (أو شيء مشابه) غير مدعوم في فينيكس. إذا وصفت حالة الاستخدام الخاصة بك ، فقد أكون قادرًا على المساعدة.

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