0

可変量の引数を持つ関数を定義するマクロがあります。マクロには、どの実際の関数を呼び出す必要があるかを決定するロジックがあります。私の現在のアプローチは次のとおりです。

#define FUNC(ret,args,args_call) \
    ret my_func(args) { \
        if( something ) other_func(args_call);\
        return one_func(args_call);\
    }
#define PARAM(...) __VA_ARGS__

私はそれを次のように使用します:

class AClass : public AInterface {
public:
    FUNC(int,PARAM(int a, int b),PARAM(a,b))
};

それを行うためのより良い方法があるかどうか疑問に思っていました。

注:宣言された(my_func私の例では)関数は、スーパークラスからメソッドを再実装するために使用されるため、テンプレート(私が知っているもの)を使用するアプローチは私の問題を解決しません。

Edit2:適切な可変個引数テンプレート関数を使用しても、スーパークラスの関数をオーバーライドするため、関数を宣言するマクロが必要です。

#define FUNC(ret,args,args_call) \
ret my_func(args) { \
    return proper_variadic_templated_function<ret>(args_call);\
}
4

1 に答える 1

0

ここでEVAL、最初の 2 つのコード ブロックの 、ヘルパー、および条件付きマクロを使用すると、 . パラメータ配列を解析するために、いくつかの再帰マクロを作成できます。

コンマは構文であるため、出力するにはエスケープする必要があります。

#define COMMA() ,

タイプと名前を分離する 2 つの関数を生成できます。

#define I_WT_R() I_WT
#define I_WT(t,v,n,...) \
    t v IS_DONE(n)(      \
        EAT               \
    ,                      \
       OBSTRUCT(COMMA)()    \
       OBSTRUCT(I_WT_R)()    \
    )(n,__VA_ARGS__)
#define WithTypes(...) I_WT(__VA_ARGS__,DONE)

と。

#define I_WoT_R() I_WoT
#define I_WoT(t,v,n,...) \
    v IS_DONE(n)(         \
        EAT                \
    ,                       \
        OBSTRUCT(COMMA)()    \
        OBSTRUCT(I_WoT_R)()   \
    )(n,__VA_ARGS__)
#define WithoutTypes(...) I_WoT(__VA_ARGS__,DONE)

マクロを次のように再定義します。

#define FUNC(ret,args) EVAL(                           \
    ret my_func(WithTypes args) {                      \
        if( something ) other_func(WithoutTypes args); \
        return one_func(WithoutTypes args);            \
    })

次のわずかに優れた構文を使用できます。

class AClass : public AInterface {
public:
    FUNC(int,(int,a,int,b))
};

コンパイルする (改行を追加した後):

class AClass : public AInterface {
public:
    int my_func(int a , int b ) {
        if( something )
            other_func(a , b );
        return one_func(a , b );
    }
};

それが役立つことを願っています。

于 2017-10-02T16:11:45.650 に答える