13

同じ名前で引数が異なる 2 つのマクロを使用することはできますか? このようなもの:

#define FI(value) do {l<<value;  Doit(l); } while(0)
#define FI(value, level) do {l<<value ; Doit(l,level); } while(0)
4

4 に答える 4

12

それは不可能。
シンボル名は再定義できません。関数とは異なり、マクロはオーバーロードできません。論理的に考えると、マクロは純粋なテキストの置換用です。では、同じエンティティの 2 つの異なるものをどのように置換できますか?

別のより良い解決策:同じ結果を得るためのインライン関数
を 作成できます。チェックの追加の利点を提供し、マクロのあいまいな副作用からあなたを救います。

于 2013-01-02T14:42:08.030 に答える
2

これはうまくいくでしょう。

#define FI(value, ...) FI_(value, ##__VA_ARGS__, 2, 1)
#define FI_(value, level, n, ...) FI##n(value, level)
#define FI1(value, ...) do {l << value; Doit(l);} while (0)
#define FI2(value, level) do {l << value; Doit(l, level);} while (0)
于 2016-04-16T20:37:27.970 に答える
1

これは、実際にインライン関数を使用する必要がある状況です。使用しているタイプについて何も知らない場合、可能な実装は次のようになります。

template<typename T>
inline void fi(T & l, const T & value) {
   l << value;
   Doit(l);
}

template<typename T>
inline void fi(T & l, const T & value, const T & level) {
   l << value;
   Doit(l, level);
}

マクロに固執しなければならない状況に遭遇した場合は、少なくとも標準に従って、マクロをオーバーロードできないというこの制限を回避する必要があります。それらを「オーバーロード」するには、マクロの名前に引数の数を書き込むだけです。これは一般的な方法です(実際、OpenGLライブラリでもこのメソッドを使用してC関数を「オーバーロード」します)。

#define FI1(value) do {l<<value;  Doit(l); } while(0)
#define FI2(value, level) do {l<<value ; Doit(l,level); } while(0)
于 2013-01-02T14:59:29.553 に答える
1

実際には可能です。ただし、再定義に関するコンパイラの警告が発生します。

詳細については、http: //efesx.com/2010/08/31/overloading-macros/を参照してください。

于 2013-01-02T14:47:42.397 に答える