首頁>Program>source

例如

class A
{
    int m_x;
    float m_y;
    double m_z;
    int x() const {return m_x;}
    float y() const {return m_y;}
    double z() const {return m_z;}
};

變得像

class A
{
    MY_MACRO((int)(float)(double), (x)(y)(z));
};

請使用boost prerocessor序列執行此操作,因為此巨集將与其他已经使用boost preprocesor序列的現有巨集結合。

最新回復
  • 9天前
    1 #

    免责宣告:您應该等待,以防出現更好的答案,即使 對這个答案感到满意,因為我距离专家還很远,而且這些方法可能不是最好的方法。

    1st approach:

    //two different sequences
    struct A
    {
        MY_MACRO1((int)(float)(double),(x)(y)(z))
    };
    

    我认為這種方法提供了看起来不太吓人的巨集:

    #define DECLARE_DATA_MEMBER1(R,TYPES,INDEX,NAME) \
    BOOST_PP_SEQ_ELEM(INDEX,TYPES) BOOST_PP_CAT(m_,NAME);
    #define DEFINE_ACCESSOR1(R,TYPES,INDEX,NAME) \
    BOOST_PP_SEQ_ELEM(INDEX,TYPES) NAME(){ return BOOST_PP_CAT(m_,NAME); }
    #define MY_MACRO1(TYPES,NAMES) \
    BOOST_PP_SEQ_FOR_EACH_I(DECLARE_DATA_MEMBER1,TYPES,NAMES) \
    public: \
    BOOST_PP_SEQ_FOR_EACH_I(DEFINE_ACCESSOR1,TYPES,NAMES)
    

    MY_MACRO 得到两个序列: TYPESNAMES .為了宣告資料成員,我使用 BOOST_PP_SEQ_FOR_EACH_I 在序列 NAMES 使用巨集 DECLARE_DATA_MEMBER1 並具有序列 TYPES 作為資料.這个"呼叫" DECLARE_DATA_MEMBER1 具有4个引數: R 没用的(我不知道它做什麼), TYPES (型別的序列), INDEX (告诉我们我们現在處於哪个迭代階段,从0開始)和 NAME (原始 NAMES的元素 与此迭代相對應的序列)。
    DECLARE_DATA_MEMBER1的"身體" 和 DEFINE_ACCESSOR1 很簡單,我们只需得到 INDEX 型別序列中的第th个元素,並連線 m_NAME


    2nd approach:

    //just one sequence but you need to put two sets of parentheses around each pair
    struct B
    {
        MY_MACRO2(((int, x))((float,y))((double,z)))
    };
    

    這仍然很簡單,但是不方便使用双括號。

    #define DECLARE_DATA_MEMBER2(R,_,TYPE_AND_NAME) \
    BOOST_PP_TUPLE_ELEM(2,0,TYPE_AND_NAME) BOOST_PP_CAT(m_,BOOST_PP_TUPLE_ELEM(2,1,TYPE_AND_NAME));
    #define DEFINE_ACCESSOR2(R,_,TYPE_AND_NAME) \
    BOOST_PP_TUPLE_ELEM(2,0,TYPE_AND_NAME) BOOST_PP_TUPLE_ELEM(2,1,TYPE_AND_NAME)(){ return BOOST_PP_CAT(m_,BOOST_PP_TUPLE_ELEM(2,1,TYPE_AND_NAME)); }
    #define MY_MACRO2(TYPES_AND_NAMES) \
    BOOST_PP_SEQ_FOR_EACH(DECLARE_DATA_MEMBER2,_,TYPES_AND_NAMES) \
    public: \
    BOOST_PP_SEQ_FOR_EACH(DEFINE_ACCESSOR2,_,TYPES_AND_NAMES)
    

    這次只有一个序列,因此我们不需要帮助巨集中的索引.由於這个原因 BOOST_PP_SEQ_FOR_EACH 使用 DECLARE_DATA_MEMBER2巨集在TyPES_AND_NAMES上使用 並且不傳遞任何額外的資料.该巨集收到三个"引數": R 再次未使用, _ (或 DATA ,此處也未使用)和 TYPE_AND_NAME (形式為 (TYPE,NAME)的元組 )。
    在两个輔助巨集 BOOST_PP_TUPLE_ELEM的"主體"中 用於获取型別(索引為0)或名稱(索引為1).需要將此巨集傳遞给元組的大小,所需元素的索引和元組。


    3rd approach:

    //one sequence but the macro is more complex
    struct C
    {
        MY_MACRO3((int,x)(float,y)(double,z))
    };
    

    此巨集从 BOOST_FUSION_ADAPT_STRUCT大量借用 和類似的巨集。

    //Heavily "inspired" from BOOST_FUSION_ADAPT_STRUCT
    #define CREATE_MY_MACRO_PLACEHOLDER_FILLER_0(X, Y)  \
        ((X, Y)) CREATE_MY_MACRO_PLACEHOLDER_FILLER_1
    #define CREATE_MY_MACRO_PLACEHOLDER_FILLER_1(X, Y)  \
        ((X, Y)) CREATE_MY_MACRO_PLACEHOLDER_FILLER_0
    #define CREATE_MY_MACRO_PLACEHOLDER_FILLER_0_END
    #define CREATE_MY_MACRO_PLACEHOLDER_FILLER_1_END
    #define DECLARE_DATA_MEMBER3(R,_,TYPE_AND_NAME) \
    BOOST_PP_TUPLE_ELEM(2,0,TYPE_AND_NAME) BOOST_PP_CAT(m_,BOOST_PP_TUPLE_ELEM(2,1,TYPE_AND_NAME));
    #define DEFINE_ACCESSOR3(R,_,TYPE_AND_NAME) \
    BOOST_PP_TUPLE_ELEM(2,0,TYPE_AND_NAME) BOOST_PP_TUPLE_ELEM(2,1,TYPE_AND_NAME)(){ return BOOST_PP_CAT(m_,BOOST_PP_TUPLE_ELEM(2,1,TYPE_AND_NAME)); }
    #define MY_MACRO3(TYPES_AND_NAMES) \
    BOOST_PP_SEQ_FOR_EACH(DECLARE_DATA_MEMBER3,_,BOOST_PP_CAT(CREATE_MY_MACRO_PLACEHOLDER_FILLER_0 TYPES_AND_NAMES,_END)) \
    public: \
    BOOST_PP_SEQ_FOR_EACH(DEFINE_ACCESSOR3,_,BOOST_PP_CAT(CREATE_MY_MACRO_PLACEHOLDER_FILLER_0 TYPES_AND_NAMES,_END))
    

    在這種方法中,輔助巨集基本上是不變的.唯一的不同是,for_each中使用的序列不只是 TYPES_AND_NAMES 但是 BOOST_PP_CAT(CREATE_MY_MACRO_PLACEHOLDER_FILLER_0 TYPES_AND_NAMES,_END) .這是強製使用双括號的聪明技巧.它是這樣的:

    CREATE_MY_MACRO_PLACEHOLDER_FILLER_0(int,x)(float,y)_END
        //CREATE_MY_MACRO_PLACEHOLDER_FILLER_0(A,B)->((A,B))CREATE_MY_MACRO_PLACEHOLDER_FILLER_1
    ((int,x))CREATE_MY_MACRO_PLACEHOLDER_FILLER_1(float,y)_END
        //CREATE_MY_MACRO_PLACEHOLDER_FILLER_1(A,B)->((A,B))CREATE_MY_MACRO_PLACEHOLDER_FILLER_0
    ((int,x))((float,y))CREATE_MY_MACRO_PLACEHOLDER_FILLER_0_END
        //CREATE_MY_MACRO_PLACEHOLDER_FILLER_0_END->
    ((int,x))((float,y))
    

    在Coliru上執行。

  • 如何在R中訪問help / documentation rd源檔案?
  • 从Javascript讀取非內聯CSS樣式資訊