問題タブ [variadic-macros]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - __VA_ARGS__ に関する問題
そこで受け入れられた答えは私にはうまくいきません。MSVC++ 10 と g++ 3.4.5 で試しました。
また、例をより小さなものに砕き、エラーでいくつかの情報を出力しようとし始めました。
ARG_N の引数が 'XXX' ではなく 'XXX' になってしまうように私には思え5,RSEQ_N
ます5,10,...,0
。g++ のエラー出力は、より具体的には、引数が 1 つしか指定されていないことを示しています。
答えが提案され、それが完全に機能しないときに受け入れられると信じるのに苦労しているので、何が間違っているのでしょうか? XXX
が引数として解釈され、展開されないのはなぜですか? 私自身のいじり回しでは、 VA_ARGSをいくつかの名前の後に ... が続くマクロに渡そうとするまで、すべてが正常に機能します。
()
入力を受け取らないさまざまなマクロで、ありとなしの両方を試しました。
c++ - 可変引数のみを取るマクロに送信された最初のパラメーターを選択する方法
可変引数マクロに送信される最初の実パラメータを取得しようとしています。これは私が試したもので、VS2010では機能しません:
プリプロセッサの出力を見るとFIRST_ARG
、送信された引数リスト全体が返されていることがわかりますMY_MACRO
...
一方、私が試してみると:
意図したとおりに 1 に展開されます。
これは、悪名高い 2 レベルの concat マクロによって解決される問題の逆のようです。「マクロパラメーターはマクロ本体に挿入される前に完全に展開される」ことは知っていますが、これがコンテキストで何を意味するのか理解できないため、ここでは役に立たないようです...そして__VA_ARGS__
明らかに__VA_ARGS__
バインドされN
、後でのみ評価されます。追加のマクロ レベルでいくつかの方法を試しましたが、役に立ちませんでした。
c++ - Variadic マクロは非標準ですか?
debugbuilds の場合、私は通常 Clang を使用します。これは、警告とエラーをより適切にフォーマットし、それらを追跡して修正するのを少し簡単にするためです。
しかし最近、可変引数を持つマクロを追加した後、Clang は (ダミー プロジェクトから) 次のことを教えてくれました。
macroname(args...)
Visualstudio、Sunstudio、そしてもちろん GCC など、さまざまなコンパイラで問題なくコンパイルできることを私は知っています。しかし、clang が正しいことを確認するために、可変引数を展開する別の 2 つの方法を試しました。
番号 1:
2番:
両方で、次のメッセージが表示されます。
... Variadic マクロが実際に C++ の標準の一部であるかどうか疑問に思います (もちろん、プリプロセッサが独立して解釈されることはわかっています)。
visual-c++ - MSVC が __VA_ARGS__ を正しく展開しない
次のコードを検討してください。
期待される出力はX = 1 and VA_ARGS = 2, 3
両方のマクロであり、GCC で得られるものですが、MSVC はこれを次のように展開します。
つまり、__VA_ARGS__
複数の引数に分割されるのではなく、単一の引数として展開されます。
これを回避する方法はありますか?
c++ - マクロ反復を使用した関数宣言の生成
マクロを使用して関数宣言を生成しようとしています
空のマクロ引数を使用して、next(name)
または(type)
byNAME
またはPARAMS
それぞれを繰り返し処理します。...
しかし、GCCは
そしてclangは不平を言う
これは次の理由で起こると思います
私は、...
または それぞれの または(name)
の引数を渡していないからです(type)
。適用できる簡単な回避策はありますか?
@James がパラメーター リストの長さを見つけるために使用する手法と同様の手法を使用しました。2 番目の引数として , の代わりに が渡された場合O
、ONT
カンマと. を出力しますNAME
。最終的な解決策は次のとおりです。
テスト:
c - 可変長マクロのトリック
選択した事前選択された境界範囲内の値にFOO(a1, a2, a3,..., an)
展開するように可変長マクロを作成するトリックは何ですか? つまり、 、 などに展開する必要があります。標準的なトリックがあることは知っていますが、見つけられないようです。FOOn(a1, a2, a3,..., an)
n
FOO(a)
FOO1(a)
FOO(a, b, c)
FOO3(a, b, c)
この質問を重複としてマークし、回答のある別の質問がある場合は閉じてください。あると思いますが見つけられませんでした。
c - GCC の ##__VA_ARGS__ トリックの標準的な代替手段?
C99 の可変個引数マクロの空の引数には、よく知られた 問題があります。
例:
上記の使用はBAR()
、C99 標準によれば、次のように展開されるため、実際には正しくありません。
末尾のコンマに注意してください - 機能しません。
一部のコンパイラ (例: Visual Studio 2010) は、末尾のコンマを静かに取り除きます。他のコンパイラ (例: GCC) は、次のよう##
に の前に置くことをサポートしています:__VA_ARGS__
しかし、この動作を取得するための標準に準拠した方法はありますか? おそらく複数のマクロを使用していますか?
現在、この##
バージョンは (少なくとも私のプラットフォームでは) 十分にサポートされているように見えますが、私はむしろ標準に準拠したソリューションを使用したいと考えています。
プリエンプティブ: 小さな関数を書けることはわかっています。マクロを使用してこれを実行しようとしています。
編集: BAR() を使用する理由の例 (単純ですが) を次に示します。
fmt
これにより、常に二重引用符で囲まれた C 文字列であると仮定して、BAR() ログ ステートメントに改行が自動的に追加されます。改行を個別の printf() として出力しません。これは、ロギングが行バッファリングされ、複数のソースから非同期的に来る場合に有利です。
c++ - ゼロ引数の可変長マクロ
私は呼び出しマクロに取り組んでいます、
呼び出されたとき、
リンクされたリストに 2 3 4 5 を追加し (, はそのためにオーバーロードされます)、print を呼び出します。これは、引数を必要としない呼び出しがいくつかあるにもかかわらず、期待どおりに機能するリンクされたリストを期待します。
それでもリンクされたリストが必要ですが、空のリストは機能しません。どちらのスタイルでも機能するマクロを考え出そうとしていますか?
編集: gcc ドキュメントを掘り下げると、 VA_ARGSの前に ## を追加すると、引数がない場合に が削除されることがわかりましたが、それではマクロをネストできません。
これにより、CALL not defined エラーが発生しますが、呼び出しを分離すると機能します
c++ - Boost.FusionのC++可変個引数マクロ?
したがって、この回答によると、C ++は可変個引数マクロをサポートしておらず、C++標準は可変個引数マクロについてどこにも言及していません。C99で可変個引数マクロが導入されたことは知っています__VA_ARGS__
。特定のC++コンパイラ(GCCなど)は、C ++でこれを可能にする拡張機能も提供しますが、可変個引数マクロは単に標準C++の一部ではないという事実は変わりません。
BOOST_FUSION_ADAPT_STRUCT
現在、Boost.Fusionには、マクロを使用してFusionシーケンスを任意のクラスまたは構造体にバインドできる機能があります。これにより、クラスまたは構造体をFusionシーケンスであるかのように使用できます。
これがどのように使用されるかの例を次に示します(Boostドキュメントから取得)。
さて、このコードは可変個引数マクロなしでどのように可能ですか?マクロはBOOST_FUSION_ADAPT_STRUCT
、おそらく任意のユーザー定義のクラスまたは構造体で機能できるため、任意の数の引数を取るようです。
Boostは興味深い方法でC++を曲げることで有名ですが、これはコンパイラのサポートなしではまったく不可能に思えます。では、Boost.Fusionはこれを実現するためにどのような魔法を使っているのでしょうか。
PS:はい、Boostがオープンソースであることは知っています。私が最初にしたことは、ソースコードを見ることでした。どういうわけかマクロを連結するためにBoostプリプロセッサライブラリを使用しているようです。しかし、これが任意の数の引数に対してどのように機能するかはわかりません。ソースコードは、非常に高密度のプリプロセッサコードのコレクションであり、理解するのが非常に困難です。
c++ - 「プレースホルダー」値を持つマクロ
プリプロセッサライブラリのセットを含むライブラリを使用しています。__VA_ARGS__
それらの1つは、を繰り返し、引数ごとにユーザー提供のマクロを呼び出すFOR_EACHスタイルのマクロです。ユーザー提供のマクロは次のように呼び出されます。SOME_MACRO(current_arg)
ただし、問題は、単一の引数を取るユーザー提供のマクロでのみ機能することです。struct
aの名前と構造体の各フィールドの両方を含む特別なことをしようとしています。問題は、これにはマクロに対して2つの引数が必要なことです。
私が使用しているライブラリは単項マクロのみを受け入れるので、マクロに追加の引数を「バインド」する方法はありますか?
今のところ、マクロで構造体の名前をハードコーディングする必要があります。したがって、struct
私が作業している名前が、である場合、私はFoo
言わなければなりません:
STRUCT
どういうわけか、マクロに2番目の引数を「バインド」して、ライブラリがマクロを呼び出すときに、次のように展開できるようにすることができますか。