このサイトで見られるように、コードは括弧内にチルダを使用したマクロ呼び出しを示しています。
HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~))
// ^^^
それはどういう意味ですか/何をしますか?ただの空の議論だと思いますが、よくわかりません。__VA_ARGS__
C99に固有であり、C ++に存在するように、C(99)に固有である可能性がありますか?
このサイトで見られるように、コードは括弧内にチルダを使用したマクロ呼び出しを示しています。
HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~))
// ^^^
それはどういう意味ですか/何をしますか?ただの空の議論だと思いますが、よくわかりません。__VA_ARGS__
C99に固有であり、C ++に存在するように、C(99)に固有である可能性がありますか?
Boost.Preprocessorの紹介ページに、 A.4.1.1水平方向の繰り返しの例が示されています。
#define TINY_print(z, n, data) data
#define TINY_size(z, n, unused) \
template <BOOST_PP_ENUM_PARAMS(n, class T)> \
struct tiny_size< \
BOOST_PP_ENUM_PARAMS(n,T) \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM( \
BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_print, none) \
> \
: mpl::int_<n> {};
BOOST_PP_REPEAT(TINY_MAX_SIZE, TINY_size, ~) // Oh! a tilde!
#undef TINY_size
#undef TINY_print
以下に説明を示します。
コード生成プロセスは、2番目の引数()で指定されたマクロを繰り返し呼び出す高次
BOOST_PP_REPEAT
マクロであるを呼び出すことによって開始されます。最初の引数は繰り返される呼び出しの数を指定し、3番目の引数は任意のデータにすることができます。呼び出されているマクロに変更されずに渡されます。この場合、はそのデータを使用しないため、渡す選択は任意でした。[5]TINY_size
TINY_size
~
(強調鉱山)
そして、メモがあります:
[5]
~
完全に恣意的な選択ではありません。@
と$
は、C ++実装がサポートする必要のある基本的な文字セットの一部ではないことを除いて、どちらも適切な選択であった可能性があります。無視されたような識別子は、マクロ展開の対象となり、予期しない結果につながる可能性があります。
したがって、チルダは引数が必要なため、単なるプレースホルダーですが、何も必要ありません。ユーザー定義の識別子は拡張できるため、別のものを使用する必要があります。
たとえば、またはと比較して、ほとんど使用されて~
いないことがわかります(バイナリ否定はそれほど頻繁には呼び出されません) 。したがって、混乱する可能性はほとんどありません。これに落ち着いたら、それを一貫して使用することで、チルダに新しい意味が与えられます。データのストリーミングに使用するのと同じように、C++のイディオムになりました。+
-
operator<<
operator>>
は~
何もしません。これらの括弧内の他のほとんどのコンテンツは同じように機能します。
このトリックの要は、の展開の_TRIGGER_PARENTHESIS_
隣にあるかどうかをテストすることです。いずれにせよ、引数をまたはに展開します。(~)
_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~)
HAS_COMMA(...)
0
1
テストする引数は、マクロとその括弧の間に配置されます。マクロは、引数が空の場合にのみトリガーされます。
_TRIGGER_PARENTHESIS_ __VA_ARGS__ (~)
注:実際には、投稿したリンクにその旨が記載されています。標準でこれへの参照を確認します。