2011-12-21 15 views
8

エンジニアリング仕様書の要​​素と同じ名前の変数が多数あります。そのため、文字列の名前も便利です。引数に展開するC/C++マクロ、文字列としての引数

私自身はこのように多くのマクロを使用して見つける:

#define MACRO(a) a, #a 

一般的な使用方法は次のとおりです。

void someFunction(int a, const char *name); 

someFunction(MACRO(meaningfully_named_variable)); 

私の質問は3つあり:

  • は、より良い方法はありますこれをする?
  • 類似のマクロはBoostや他のライブラリで利用できますか?
  • もしそうでなければ、私はそれを明確かつ有用なものにするためにどのように修正して名前を変更できますか?

編集 私は上記の最小限の例であると述べている必要があります。関数には他のパラメータがあり、名前付きエンティティはデータメンバでも、関数自体でも構いません。

私がC++を考えているもう一つの拡張は、マクロの内容を受け取ることができるクラスNamedRefです。

template <typename T> 
struct NamedRef 
{ 
    NamedRef(T *t, const char *name) : t(t), name(name) { } 
    T *t; 
    const char *name; 
}; 

template <typename T> 
NamedRef<T> namedRef(T &t, const char *name) 
{ 
    return NamedRef<T>(&t, name); 
} 

#define WITH_NAME(a) a, #a 

// more sophisticated usage example 
void otherFunction(double, NamedRef<int>, bool); 

otherFunction(0.0, namedRef(object.WITH_NAME(meaningful_member_name)), false); 
+3

私がしたいのは、マクロのよりわかりやすい名前を選択することです。 'WITH_NAME()' –

+0

@MarkRansomが提案したことを実行してください。私の答えは「大丈夫です」と言っている長い言葉でした.BoostにはBOOST_STRINGIZE(X)というマクロがあります。 – AusCBloke

答えて

5

あなたはさらに一歩それを取ることができます:

#define SOMEFUNCTION(a) somefunction(a, #a) 

をしかし、これはあなたが同じ機能の多くを呼び出した場合にのみ有効です。そうでなければ、私はあなたの例よりも良い方法はないと思います。もちろん、ARGUMENTSなどのように、マクロの名前をもっと意味のあるものに変更する必要があります。

+0

本当ですが、 'var、name'を受け取る関数がたくさんある場合は、たくさんのマクロを書く必要があります。 – paperjam

+0

必ずしも=> '#define MACRO(funct_ptr、var)funct_ptr(var、#var)' このように多くのマクロには、あなたが持っている関数パラメータのいくつかの異なるシグネチャが必要です... –

+0

可能であれば、関数構文を保存することがより明確であると思います。また、関数には他のargがあるかもしれません。 – paperjam

0
#define someFunction(a) if (1) stringized_someFunction((a), #a); else (void)0 
void stringized_someFunction(int a, const char* name); 

あなたがそのようにように、あなたの関数を呼び出すと、それはなどのループ、枝、if文で混乱(通常)、

ないように、(1)のものは、マクロをアップラップした場合ザ・:

int r = 4; 
someFunction(r); 

「関数宣言」ごとに1行追加するだけです。 Cプリプロセッサが複数のステップを許可した場合、すべてのステップを1つにまとめることができますが、うまくいきません。

void stringized_someFunction(int a, const char* name) 
{ 
    // Do stuff here 
} 

とにかく、そのように読むことを非常に簡単かつきれいにする必要があります:私はあなたがあなたの関数を書く必要があるだろうことは明らかです願っていますので、

私は忘れてしまいました。

+1

あなたはマクロ定義のセミコロンを忘れてしまいました。また、このような状況では(1)が必要であれば包み込むとは思わない。 –

+0

@Jesseありがとう。 if(1)が常に必要です。 –

+1

私はあなたが[複数のステートメントマクロをラップする必要がある]ことを知っています(http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Multi-statement_Macro)、コードを壊さないようにしていますが、わかりませんあなたが反例を提示できれば、それは評価されるでしょう。 –

0

ジェシーは、あなたがこのように書くことができ、

に答えとして:あなたは合格するより多くの引数を持つ

void function1(int a, const char* name) 
{ 
    cout << "a: " << a << endl; 
    cout << "name: " << name << endl; 
} 

void function2(double d, const char* name, const char *str) 
{ 
    cout << "d: " << d << endl; 
    cout << "name: " << name << endl; 
    cout << "str: " << str << endl; 
} 

#define MACRO(functionName, a) functionName(a, #a) 
#define MACRO2(functionName, a, ...) functionName(a, #a, __VA_ARGS__) 

int main() 
{ 
    int a = 10; 
    MACRO(function1, a); 
    double d = 10.5; 
    MACRO2(function2, d, "Hello world"); 
    return 0; 
} 

場合は、変数の引数を使用していますMacro2ではを使用することができます。それに応じて関数名を渡す必要があります。

関連する問題