[解決済み] C/C++マクロのカンマ
2022-09-11 10:08:02
質問
次のようなマクロがあるとします。
#define FOO(type,name) type name
のように使うことができます。
FOO(int, int_var);
しかし、必ずしもそのように単純なものではありません。
FOO(std::map<int, int>, map_var); // error: macro "FOO" passed 3 arguments, but takes just 2
もちろん、できるはずです。
typedef std::map<int, int> map_int_int_t;
FOO(map_int_int_t, map_var); // OK
というのは、あまり人間工学的ではありません。さらに、型の非互換性にも対処しなければなりません。マクロでこれを解決する方法はないでしょうか?
どのように解決するのですか?
山括弧は比較演算子を表す(またはその中に現れる)こともあるため
<
,
>
,
<=
と
>=
のように、角括弧内のカンマをマクロ展開で無視することはできません。 (これは角括弧と中括弧の問題でもあります。これらは通常、バランスの取れたペアとして発生しますが)。 マクロ引数を括弧で囲むことができます。
FOO((std::map<int, int>), map_var);
問題は、パラメータがマクロ展開の内部で括弧で囲まれたままであるため、ほとんどのコンテキストで型として読み取られないことです。
これを回避するための素晴らしいトリックは、C++では、関数型を使用して括弧で囲まれた型名から型名を抽出することができるということです。
template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };
#define FOO(t,name) argument_type<void(t)>::type name
FOO((std::map<int, int>), map_var);
関数型の形成は余分な括弧を無視するので、型名にカンマが含まれない場合は括弧を付けても付けなくてもこのマクロを使用することができます。
FOO((int), int_var);
FOO(int, int_var2);
C言語では、型名が括弧の外にカンマを含むことができないので、もちろんこれは必要ない。 ですから、言語横断的なマクロの場合、こう書くことができます。
#ifdef __cplusplus__
template<typename T> struct argument_type;
template<typename T, typename U> struct argument_type<T(U)> { typedef U type; };
#define FOO(t,name) argument_type<void(t)>::type name
#else
#define FOO(t,name) t name
#endif
関連
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み】std::cin.getline( ) vs. std::cin
-
[解決済み】CMakeでプリプロセッサー・マクロを定義する?
-
[解決済み】引数の個数でマクロをオーバーロードする方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】関数名の前に期待されるイニシャライザー
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】Visual Studio 2013および2015でC++コンパイラーエラーC2280「削除された関数を参照しようとした」が発生する
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない
-
[解決済み】c++で.txtファイルから2次元の配列に読み込む