إجبار المعالج المسبق على استخدام تعريف سابق في إعادة تعريف

StackOverflow https://stackoverflow.com/questions/1384946

سؤال

تحديث 3:

لا يهم. لقد حصلت على ما كنت أبحث عنه. فيما يلي يعطي معرفات فريدة داخل الفصل.

static const int _counter_start = __COUNTER__;
static const int val1 = __COUNTER__ - _counter_start;
static const int val2 = __COUNTER__ - _counter_start;

تحديث 2:

تعزيز المعالج المسبق

سأقوم بتنفيذ شيء أقرب إلى خريطة الرسائل مع هذه الوظيفة.

class a
{
...
    MAP_BEGIN()
    MAP_DECL...
    MAP_END()
...
};

الشيء ، لكل map_decl ، أحتاج إلى توسيع الماكرو في مكانين.

class a
{    
    virtual void func()
    {        
        ...
        //does something with the decl declaration        
    }
    ...
    //also expand some stuff here    
}

يجب أن يسمح لي Boost Preprocessor (نظريًا) بتجميع MAP_DECL في تسلسل وتوسيعه إلى func () في النهاية (مع توسيع حقول الفصل في وقت واحد كما نذهب).


تحديث 1:

أنا أستخدم مكتبة Boost Preprocessor في الوقت الحالي. أنا عالق حاليًا إنشاء متغير/تعريف ماكرو جديد مثل ما يلي في كل مرة أحتاج فيها إلى إضافة شيء إلى التسلسل.

أحاول توسيع تسلسل تعزيز المعالج المسبق وأنا عالق في القيام بذلك في الوقت الحالي

#define SEQ (w)(x)(y)(z) 
#define SEQ2 BOOST_PP_SEQ_PUSH_BACK(SEQ, a)

أصلي:

افترض أن لدي الرمز التالي

#define CUR 2
#define CUR CUR + 2

كيف أجبر الخط الثاني على استخدام قيمة cur من السطر الأول؟

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

المحلول

بإيجاز ، لا يمكنك.

في الوقت الذي يتم فيه توسيع CUR (بعد الثانية #define) ، سيحل المعالج المسبق محل مثيل CUR بـ CUR + 2 ، و "الطلاء الأزرق" باسم Cur (لا يوسعه أكثر). بعد ذلك ، يرى برنامج التحويل البرمجي C Cur + 2 ، والذي يحقق على الأرجح خطأ في التجميع.

نصائح أخرى

حتى لو كان بإمكانك فعل ذلك ، فهذا أمر خطير.
مثال:

#define CUR 2
#define CUR CUR + 2
...
int x = CUR*4; // x = 2 + 2 * 4

لا يمكنك القيام بذلك ، يمكنك فقط تحديد كل ماكرو مرة واحدة ، وإلا فإن المترجم سوف يسكب خطأ.

حاولت القيام بشيء مماثل عند نقطة واحدة (إلحاق بتعزيز تسلسل المعالج المسبق). لقد ضربت الجدار بقوة (بسبب ما قاله جوناثان في إجابته) وانتهى بي الأمر بعمل شيء مختلف تمامًا.

في وقت لاحق ، وجدت أن تسلسل نوع MPL Boost لها نفس القيد الفعال (وهو أمر منطقي تمامًا ، لكن في بعض الأحيان لا ترى جدارًا حتى تصطدم به بالفعل :)).

يجب عليك تحديد التسلسل الكامل أو إعطائه اسمًا مختلفًا.

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

#define MAP_BEGIN std::vector<Message> m_messages; \
  void buildMap() {
#define MAP_END }
#define MAP_DECL(...) m_messages.push_back(...);

إذا كانت كل رسالة من النوع منفصل ، فحاول محو النوع (Boost :: any) أو اجعلها ترث من بعض الفئات الأساسية وتخزينها.

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