同じ名前で引数が異なる 2 つのマクロを使用することはできますか? このようなもの:
#define FI(value) do {l<<value; Doit(l); } while(0)
#define FI(value, level) do {l<<value ; Doit(l,level); } while(0)
同じ名前で引数が異なる 2 つのマクロを使用することはできますか? このようなもの:
#define FI(value) do {l<<value; Doit(l); } while(0)
#define FI(value, level) do {l<<value ; Doit(l,level); } while(0)
それは不可能。
シンボル名は再定義できません。関数とは異なり、マクロはオーバーロードできません。論理的に考えると、マクロは純粋なテキストの置換用です。では、同じエンティティの 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)
これは、実際にインライン関数を使用する必要がある状況です。使用しているタイプについて何も知らない場合、可能な実装は次のようになります。
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)
実際には可能です。ただし、再定義に関するコンパイラの警告が発生します。
詳細については、http: //efesx.com/2010/08/31/overloading-macros/を参照してください。