2011-01-28 11 views
4

私のような任意の引数を取るC++のマクロを書きたいですか?C++マクロのテキスト操作

は、この一見贅沢な質問で私を助けるため、事前にいただきありがとうございます:)

+0

"m_a"から "m"を削除したいですか? – Nawaz

+3

マクロのパラメータから先頭のm_を取り除くことは難しいと思います。しかし、マクロとC++は、彼らが何であるかを、私は "不可能"と言うことをためらっています... –

+0

はい、2つの問題があります:m_を取り除き、__VA_ARGS__の各引数に ""を追加する – stepelu

答えて

6

m_aからaに簡単に行くことはできません。ただし、stringize演算子#は標準CおよびC++の一部です。次いでSTRING(m_a)

#define STRING(x) #x 

を与え例えば

は、"m_a"に変換されます。

0

をそれはの#defineを処理するものである(プリプロセッサを持っていることは本当にことはできませんC++コンパイラ自体ではなく)、引数を部分に分解します。したがって、m_aから抽出しようとしている場合、それはできません。代わりに、マクロを定義する方が良いでしょう:

 
    #define MANIP(m, a, b, c) 

そして、 'm'を別の入力にする必要があります。

第2に、文字列以外の入力から文字列入力に簡単に変換できません。 IEのから"a"から変換することは容易ではありません。私はCPP(C-Pre-processor)がそれを行うことができることを知って以来、私はそう言い方を変えています。しかし、私はそれが移植可能だとは思わない。

複雑なことをしようとするときは、ではなく、CPPよりものプログラミング言語で作業する必要があります。

具体的には、C++には、CPPの#define文よりもはるかに遠くにできるテンプレートがあります。

+4

文字列マクロ操作#a - ボグの標準です。 –

+0

明確にするために、私はC++のマクロ操作で完璧です。なぜなら、C++でサポートされるようになるからです。私はテンプレートについて知っていますが、私が提案した解決策に直面している特定の問題については、最良のものになるでしょう。 2番目に良いのはMANIP(a、b、c)を書く方が簡単なはずです(私は__VA_ARGS__の各引数を1つの引数で別のマクロに転送する方法を知っています)。 – stepelu

0

プリプロセッサーはトークンを分割できません。これは、foom_fooまたは(最近質問されたように)fooから"foo"に製造することが不可能であることを意味します。

Variadicマクロを使用できる場合(Matthieu M.が指摘するように、これはC99またはC++ 0xを意味します)、Jens GustedtのP99 libraryが参考になります。これをさらに簡単にするためのマクロがありますが、これはライブラリに慣れていない人にも読めるようにしましょう。

簡略化されたケース:2つまたは3つの引数が渡されます。

#define MANIP2(a, b) \ 
    f(a, b)   \ 
    g(#a, #b) 

#define MANIP3(a, b, c) \ 
    f(a, b, c)   \ 
    g(#a, #b, #c) 

#define MANIP(...) \ 
    MANIP_(   \ 
     P99_PASTE2(MANIP, P99_NARG(__VA_ARGS__)), \ 
     __VA_ARGS__) \ 

#define MANIP_(MANIPMAC, ...) MANIPMAC(__VA_ARGS__) 

これは基本原理を示しています。実際には、これをコード化しやすくするためにforeachスタイルのマクロ(Boostのものに似ています)があります(しかし、私が言及したように、初心者では読みにくいです)。詳細は、P99 library documentationを参照してください。